C语言-switch

C语言-switch

switch(情况){
    case 1:
    //执行代码;
    break;
    case 2:
    //执行代码;
    break;
    case 3:
    //执行代码;
    break;
    case 4:
    //执行代码;
    break;
    default:
    //如果没有以上的情况,则执行default中的语句
    break;
}

以上是switch使用的基本格式,它会通过输入的情况跳转到对应的 case语句处,然后往下执行。如有特殊情况则执行default。

switch的反汇编

​ 当switch当中的case(情况)语句小于4条时,它的反汇编和if语句基本一样。反汇编是通过cmp去和情况一一做比较然后je跳转。但当case(情况)语句大于3条的时候,它会选择直接通过参数计算出对应程序的地址。

//汇编代码
mov eax,dword ptr [ebp+8]	//将我们传入的参数(ebp+8)给到寄存器eax中
mov dword ptr [ebp-4],eax	//讲传入的参数放入ebp-4(计数器、计数)
mov ecx,dword ptr [ebp-4]	//把这个计数放入ecx中进行情况查看
sub ecx,1					//编译器认为最小的情况认为是0,这样便于安排地址(更节省空间)
mov dword ptr [ebp-4],ecx	//将寄存器认为情况值放入计数器中
cmp dword ptr [ebp-4],3		//将输入的情况与编译器认为的最大情况进行比较看是否超过
ja xxxxxxxx					//如果大于了最大情况,那么我们直接结束该指令
mov edx,dword ptr [ebp-4]	//将计数器中的值放入到edx中,方便计算指令地址
jmp dword ptr [edx*4+基址]	//通过edx*4加上基址,进行偏移寻址,跳转到对应情况的指令地址处(生成大表)
情况0的指令地址处
情况1的指令地址处
情况2的指令地址处
情况3的指令地址处
情况4的指令地址处
xxxxxxxx					//ja跳转到的指定处

小结:

[edx*4+基址]生成大表,通过表查询地址

1、如果我们设置的情况值是连续的,则编译器为了节省内存会通过[edx*4+基址]的方式来跳转到对应情况处的指令地址(连续分配)。在设置情况值时可以是无序的。(先设case5,再设case1这些都可以)

2、如果我们设置的情况值不是连续的,或者小于四种情况,那么为了提高效率,编译器会选择直接用je语句直接判断跳转。

3、当我们最小的情况值为n的时候,我们的 sub ecx ,n 语句也会相应的减n

4、ja是一个很神奇的跳转,只有当CF(进位标志寄存器)和ZF(进位标志寄存器)都为0时才不跳转,有一个不为0就跳转。说这个是为了解释它是怎么判断我们传入的数正好是在我们设置的连续的情况值范围内的。

5、当我连续的情况值中间出现了中断之后,编译器会选择将default的地址放入到中断位置。

6、但是当我们中断的范围太大时,(用default的地址填表太浪费空间资源了)这时候就会产生小表。

//产生小表
xor edx,edx							//清空edx寄存器用来存储小表地址
mov dl,byte ptr (小表)[eax]		//在小表通过eax来偏移找到大表的偏移量就得到了对应情况的指令地址。相当于我只用了一个字节去记录指令地址的偏移量
jmp dword ptr [edx*4+大表基址]

7、小表最大256个字节,如果偏移超过了这个大小就会放弃用小表记录偏移

8、当情况值之间有巨大间隔时,编译器会选择二叉树查找的方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿拉垮神登

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值