C语言-switch
switch(情况){
case 1:
//执行代码;
break;
case 2:
//执行代码;
break;
case 3:
//执行代码;
break;
case 4:
//执行代码;
break;
default:
//如果没有以上的情况,则执行default中的语句
break;
}
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跳转到的指定处
//产生小表
xor edx,edx //清空edx寄存器用来存储小表地址
mov dl,byte ptr (小表)[eax] //在小表通过eax来偏移找到大表的偏移量就得到了对应情况的指令地址。相当于我只用了一个字节去记录指令地址的偏移量
jmp dword ptr [edx*4+大表基址]