x86 下的实现
switch-case 的地址跳转表。 (有优化)
vc6 下的结果。
8: switch(i) {
00401275 cmp dword ptr [ebp-8],4
00401279 ja $L7984+0Fh (004012d0)
0040127B mov ecx,dword ptr [ebp-8]
0040127E jmp dword ptr [ecx*4+4012FDh]
9: case 0:
10: printf("it's 0/n");
00401285 push offset string "it's 0/n" (0043e064)
0040128A call printf (00408750)
0040128F add esp,4
11: break;
00401292 jmp $L7984+1Ch (004012dd)
12: case 1:
13: printf("it's 1/n");
00401294 push offset string "it's 1/n" (0043e058)
00401299 call printf (00408750)
0040129E add esp,4
14: break;
004012A1 jmp $L7984+1Ch (004012dd)
。。。。。。
ida 下的结果。
.text:004012FD off_4012FD dd offset loc_401285 ; DATA XREF: main+2Er
.text:00401301 dd offset loc_401294
.text:00401305 dd offset loc_4012A3
.text:00401309 dd offset loc_4012B2
.text:0040130D dd offset loc_4012C1
这里我只是想说明一下地址跳转表及其指令: jmp dword ptr [ecx*4+4012fdh]
显然寻址方式是一个基地址0x4012fd 加一个偏移量ecx*4. 构成数据地址,然后取数。
这个寻址方式,基地址是一个常量,而偏移地址是一个变量,而这个变量还可以有简单运算,由寄存器*4表示。
PS: 从程序中看出,立即寻址和直接寻址占有重要成分,立即寻址用于计算,直接寻址用于函数调用和跳转。
然后是内存操作。 取到内存数据。