Swithch反汇编(四种)
------------恢复内容开始------------
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反汇编(四种)的更多相关文章
- C++中四种类型转换以及const_cast是否能改变常量的问题
we have four specific casting operators:dynamic_cast, reinterpret_cast, static_cast and const_cast. ...
- 两个变量交换的四种方法(Java)
对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) class TestEV //创建一个类 { public static ...
- Android开发之基本控件和详解四种布局方式
Android中的控件的使用方式和iOS中控件的使用方式基本相同,都是事件驱动.给控件添加事件也有接口回调和委托代理的方式.今天这篇博客就总结一下Android中常用的基本控件以及布局方式.说到布局方 ...
- TCP四种计时器
TCP共使用以下四种计时器,即重传计时器.坚持计时器.保活计时器和时间等待计时器 .这几个计时器的主要特点如下: 1.重传计时器 当TCP发送报文段时,就创建该特定报文段的重传计时 ...
- C++四种类型转换方式。
类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比 ...
- C#批量插入数据到Sqlserver中的四种方式
我的新书ASP.NET MVC企业级实战预计明年2月份出版,感谢大家关注! 本篇,我将来讲解一下在Sqlserver中批量插入数据. 先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的 ...
- 织梦DedeCMS模板防盗的四种方法
织梦(DedeCMS)模板也是一种财富,不想自己辛辛苦苦做的模板被盗用,在互联网上出现一些和自己一模一样的网站,就需要做好模板防盗.本文是No牛收集整理自网络,不过网上的版本都没有提供 Nginx 3 ...
- 四种比较简单的图像显著性区域特征提取方法原理及实现-----> AC/HC/LC/FT。
laviewpbt 2014.8.4 编辑 Email:laviewpbt@sina.com QQ:33184777 最近闲来蛋痛,看了一些显著性检测的文章,只是简单的看看,并没有深入的研究,以 ...
- 像画笔一样慢慢画出Path的三种方法(补充第四种)
今天大家在群里大家非常热闹的讨论像画笔一样慢慢画出Path的这种效果该如何实现. 北京-LGL 博客号@ligl007发起了这个话题.然后各路高手踊跃发表意见.最后雷叔 上海-雷蒙 博客号@雷蒙之星 ...
- 让一个图片在div中居中(四种方法)
第一种方法: <div class="title"> <div class="flag"></div> <div cl ...
随机推荐
- 以SQLserver为例的Dapper详细讲解
Dapper是一种轻量级的ORM(对象关系映射)工具,它提供了高效且易于使用的方式来执行数据库操作.Dapper是由Stack Overflow团队开发并维护的,它的主要目标是提供比EF更快.更直接的 ...
- go中 for循环的坑
go中 for循环的坑 在使用for循环修改结构体切片中的值时,发现并没有修改成功. type Dog struct { name string } func (d *Dog) setNewName( ...
- ffmpeg音视频基础学习
ffmpeg音视频基础学习 从去年开始了解音视频,中间也由于项目的需要,学习过ffmpeg.live555.以及QTAV框架,一直没总结过,现在大致总结下音视频中的常见词汇,后续慢慢更新添加!博客也会 ...
- Nuxt3环境变量配置
Nuxt3 正式发布还不到半年,在投入生产环境使用后,遇到了不少问题,很难找到合适的解决方案,其中环境变量配置就是其中一个,之前一直未能解决,最近要上持续集成,无法绕过这个问题,所以花了点时间研究了一 ...
- 飞行时间技术TOF
文章目录 飞行时间技术TOF 一. 光速的测定 二. 各种TOF技术 直接脉冲TOF 脉冲间接TOF 连续波调制TOF(Continous Wave TOF) 三. TOF技术的应用 飞行时间技术TO ...
- .gitignore 文件语法介绍
.gitignore 文件的作用 A gitignore file specifies intentionally untracked files that Git should ignore. Fi ...
- 在Winform分页控件中集成保存用户列表显示字段及宽度调整设置
在Winform的分页控件里面,我们提供了很多丰富的功能,如常规分页,中文转义.导出Excel.导出PDF等,基于DevExpress的样式的分页控件,我们在其上面做了不少封装,以便更好的使用,其中就 ...
- 2022-11-27:超过经理收入的员工。编写一个SQL查询来查找收入比经理高的员工。以下数据的结果输出是Joe,因为Joe是唯一挣得比经理多的雇员。 DROP TABLE IF EXISTS `em
2022-11-27:超过经理收入的员工.编写一个SQL查询来查找收入比经理高的员工.以下数据的结果输出是Joe,因为Joe是唯一挣得比经理多的雇员. DROP TABLE IF EXISTS `em ...
- 2020-10-18:java中LongAdder和AtomicLong有什么区别?
福哥答案2020-10-18:#福大大架构师每日一题# 简单回答:AtomicLong是CAS操作.LongAdder是多个单元操作. 中级回答:AtomicLong 是基于 CAS 方式自旋更新的: ...
- vue全家桶进阶之路7:Vue的第一个程序
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...