------------恢复内容开始------------

Switch语法格式

Switch(表达式)
{
case 常量表达式1:
语句;
break;
case 常量表达式2:
语句;
break;
case 常量表达式3:
语句;
break;
default:
语句;
break;
}

Switch注意事项

  • case后面必须是常量表达式
  • case后常量表达式的值不一样
  • switch后面表达式必须为整数类型其它类型诸如float double 等类型均不可以
  • case如果没有添加break语句则会继续向下执行下面的case
  • dafault语句可以没有,如果所有case都不匹配会默认执行default语句

分支语句的增加之反汇编

分支语句少于等于3条与if—else语句的反汇编相同(case 值连续)

0040103E   cmp         dword ptr [ebp-4],1
00401042 je tast+32h (00401052)
00401044 cmp dword ptr [ebp-4],2
00401048 je tast+41h (00401061)
0040104A cmp dword ptr [ebp-4],3
0040104E je tast+50h (00401070)
00401050 jmp tast+5Fh (0040107f)
00401052 push offset string "1" (00422028)
00401057 call printf (00401130)
0040105C add esp,4
0040105F jmp tast+6Ch (0040108c)
00401061 push offset string "2" (00422024)
00401066 call printf (00401130)
0040106B add esp,4
0040106E jmp tast+6Ch (0040108c)
00401070 push offset string "4" (00422020)
00401075 call printf (00401130)
0040107A add esp,4
0040107D jmp tast+6Ch (0040108c)
0040107F push offset string "5" (0042201c)

分支语句大于三条生成一张大表(但是不一定,假如差值大的话就会生成if—else)(case后面的常量可以时无序的,并不影响大表的生成)编译的时候就把地址排好了

#include "stdafx.h"
void test(int x)
{ switch(x)
{
case 2:
printf("2");
break;
case 3:
printf("3");
break;
case 4:
printf("4");
break;
case 5:
printf("5");
break;
case 6:
printf("6");
break;
default:
printf("5");
break;
}
}
int main(int argc, char* argv[])
{
test(5);
return 0;
}

case的值是从100-109汇编代码如下:

0040D7D8   mov         eax,dword ptr [ebp+8]
0040D7DB mov dword ptr [ebp-4],eax
0040D7DE mov ecx,dword ptr [ebp-4]
0040D7E1 sub ecx,64h // 这个是第一个case
0040D7E4 mov dword ptr [ebp-4],ecx
0040D7E7 cmp dword ptr [ebp-4],9 //这是case的总个数 :9+1
0040D7EB ja $L550+0Fh (0040d897)
0040D7F1 mov edx,dword ptr [ebp-4]
0040D7F4 jmp dword ptr [edx*4+40D8B5h]//这就是生成的表
$L532:
0040D7FB push offset string "100" (00422fc0)
0040D800 call printf (00401130)
0040D805 add esp,4
0040D808 jmp $L550+1Ch (0040d8a4)
$L534:
0040D80D push offset string "101" (00422fbc)
0040D812 call printf (00401130)
0040D817 add esp,4
0040D81A jmp $L550+1Ch (0040d8a4)
$L536:
0040D81F push offset string "102" (00422fb8)
0040D824 call printf (00401130)
0040D829 add esp,4
0040D82C jmp $L550+1Ch (0040d8a4)
$L538:
0040D82E push offset string "103" (00422fb4)
0040D833 call printf (00401130)
0040D838 add esp,4
0040D83B jmp $L550+1Ch (0040d8a4)
$L540:
0040D83D push offset string "104" (00422fb0)
0040D842 call printf (00401130)
0040D847 add esp,4
0040D84A jmp $L550+1Ch (0040d8a4)
$L542:
0040D84C push offset string "105" (00422fac)
0040D851 call printf (00401130)
0040D856 add esp,4
0040D859 jmp $L550+1Ch (0040d8a4)
$L544:
0040D85B push offset string "106" (00422f5c)
0040D860 call printf (00401130)
0040D865 add esp,4
0040D868 jmp $L550+1Ch (0040d8a4)
$L546:
0040D86A push offset string "107" (00422028)
0040D86F call printf (00401130)
0040D874 add esp,4
0040D877 jmp $L550+1Ch (0040d8a4)
$L548:
0040D879 push offset string "108" (00422024)
0040D87E call printf (00401130)
0040D883 add esp,4
0040D886 jmp $L550+1Ch (0040d8a4)
$L550:
0040D888 push offset string "109" (00422020)
0040D88D call printf (00401130)
0040D892 add esp,4
0040D895 jmp $L550+1Ch (0040d8a4)
0040D897 push offset string "6" (0042201c)
0040D89C call printf (00401130)

说明ja 指令 jump above,大于时跳转(无符号),也就是比较参数x-1和3(case中的最大差值),最大差值就是最大值减最小值



得出的结论会给生成一个大表来直接查询

我们假如把case里面的值删除两个项会发生什么变化

#include<stdio.h>
#include "stdafx.h"
void test(int x)
{ switch(x)
{
case 100:
printf("100");
break;
case 103:
printf("103");
break;
case 104:
printf("104");
break;
case 105:
printf("105");
break;
case 106:
printf("106");
break;
case 107:
printf("107");
break;
case 108:
printf("108");
break;
case 109:
printf("109");
break;
default:
printf("5");
break;
}
}
int main(int argc, char* argv[])
{
test(106);
return 0;
}





总结删除两个时,编译器仍然生成大表来存储,没有case的值 会存储默认的地址

当删除到6个时编译器会帮我们创建小表

#include<stdio.h>
#include "stdafx.h"
void test(int x)
{ switch(x)
{
case 100:
printf("100");
break; case 107:
printf("107");
break;
case 108:
printf("108");
break;
case 109:
printf("109");
break;
default:
printf("5");
break;
}
}
int main(int argc, char* argv[])
{
test(106);
return 0;
}











小表用来存放并不存在的case,然后通过大表来寻找到default

case后面常量表达式改成好不连续的值

#include<stdio.h>
#include "stdafx.h"
void test(int x)
{ switch(x)
{
case 1:
printf("100");
break; case 5:
printf("107");
break;
case 200:
printf("108");
break;
case 9:
printf("109");
break;
case 300:
printf("109");
break;
default:
printf("5");
break;
}
}
int main(int argc, char* argv[])
{
test(103);
return 0;
}

------------恢复内容结束------------

Swithch反汇编(四种)的更多相关文章

  1. C++中四种类型转换以及const_cast是否能改变常量的问题

    we have four specific casting operators:dynamic_cast, reinterpret_cast, static_cast and const_cast. ...

  2. 两个变量交换的四种方法(Java)

    对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) class TestEV //创建一个类 { public static ...

  3. Android开发之基本控件和详解四种布局方式

    Android中的控件的使用方式和iOS中控件的使用方式基本相同,都是事件驱动.给控件添加事件也有接口回调和委托代理的方式.今天这篇博客就总结一下Android中常用的基本控件以及布局方式.说到布局方 ...

  4. TCP四种计时器

    TCP共使用以下四种计时器,即重传计时器.坚持计时器.保活计时器和时间等待计时器 .这几个计时器的主要特点如下:      1.重传计时器      当TCP发送报文段时,就创建该特定报文段的重传计时 ...

  5. C++四种类型转换方式。

    类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比 ...

  6. C#批量插入数据到Sqlserver中的四种方式

    我的新书ASP.NET MVC企业级实战预计明年2月份出版,感谢大家关注! 本篇,我将来讲解一下在Sqlserver中批量插入数据. 先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的 ...

  7. 织梦DedeCMS模板防盗的四种方法

    织梦(DedeCMS)模板也是一种财富,不想自己辛辛苦苦做的模板被盗用,在互联网上出现一些和自己一模一样的网站,就需要做好模板防盗.本文是No牛收集整理自网络,不过网上的版本都没有提供 Nginx 3 ...

  8. 四种比较简单的图像显著性区域特征提取方法原理及实现-----> AC/HC/LC/FT。

    laviewpbt  2014.8.4 编辑 Email:laviewpbt@sina.com   QQ:33184777 最近闲来蛋痛,看了一些显著性检测的文章,只是简单的看看,并没有深入的研究,以 ...

  9. 像画笔一样慢慢画出Path的三种方法(补充第四种)

    今天大家在群里大家非常热闹的讨论像画笔一样慢慢画出Path的这种效果该如何实现. 北京-LGL 博客号@ligl007发起了这个话题.然后各路高手踊跃发表意见.最后雷叔 上海-雷蒙 博客号@雷蒙之星 ...

  10. 让一个图片在div中居中(四种方法)

    第一种方法: <div class="title"> <div class="flag"></div> <div cl ...

随机推荐

  1. 劲(很)霸(不)酷(好)炫(用)的NLP可视化包:Dodorio 使用指北

    朋友们,朋友们,事情是这样的.最近心血来潮,突然想起很久以前看过的一个NLP可视化包.它的效果是下面这个样子: 在此之前,已经有一些文章从论文的角度对这个包进行了介绍,详情请见 推荐一个可交互的 At ...

  2. Vue+echarts实现中国地图射线效果

    效果图如上 前提是安装Echarts并引入 并且配置中国地图json文件这些都在同账号另一篇博客上有说明,查看请自行移步 下展示代码 <template> <div class=&q ...

  3. vue刷新当前组件的方法

    一:v-if控制组件,先设false,再true强制刷新组件(有时会产生一种奇怪的效果) 1 <medical-record v-if="fresh" /> 2 3 t ...

  4. pyhton内置函数

    内置函数 1.type(变量名)-> class 查看变量的数据类型 2.print(self, *args, sep=' ', end='\n', file=None) sep:指定多个参数以 ...

  5. 2022-12-12:有n个城市,城市从0到n-1进行编号。小美最初住在k号城市中 在接下来的m天里,小美每天会收到一个任务 她可以选择完成当天的任务或者放弃该任务 第i天的任务需要在ci号城市完成,

    2022-12-12:有n个城市,城市从0到n-1进行编号.小美最初住在k号城市中 在接下来的m天里,小美每天会收到一个任务 她可以选择完成当天的任务或者放弃该任务 第i天的任务需要在ci号城市完成, ...

  6. 2022-07-31:给出一个有n个点,m条有向边的图, 你可以施展魔法,把有向边,变成无向边, 比如A到B的有向边,权重为7。施展魔法之后,A和B通过该边到达彼此的代价都是7。 求,允许施展一次魔法

    2022-07-31:给出一个有n个点,m条有向边的图, 你可以施展魔法,把有向边,变成无向边, 比如A到B的有向边,权重为7.施展魔法之后,A和B通过该边到达彼此的代价都是7. 求,允许施展一次魔法 ...

  7. 2022-02-22:机器人大冒险。 力扣团队买了一个可编程机器人,机器人初始位置在原点(0, 0)。小伙伴事先给机器人输入一串指令command,机器人就会无限循环这条指令的步骤进行移动。指令有两种

    2022-02-22:机器人大冒险. 力扣团队买了一个可编程机器人,机器人初始位置在原点(0, 0).小伙伴事先给机器人输入一串指令command,机器人就会无限循环这条指令的步骤进行移动.指令有两种 ...

  8. 2021-09-03:直线上最多的点数。给你一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。力扣149。

    2021-09-03:直线上最多的点数.给你一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点.求最多有多少个点在同一条直线上.力扣149. 福大大 ...

  9. js通过className删除元素

    有时候难免需要使用js进行 dom 操作:如在删除地图feature时同时得清除提示框 这个就需要使用 .parentNode.removeChild(元素) let chArr = document ...

  10. OODO有关账户account模块学习

    一.记账凭证(Account Move) 会计上的记账凭证,也叫会计分录,在Odoo中叫"Account Move".Account Move直译是"账户移动" ...