x86 switch-case 的地址跳转表

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: 从程序中看出,立即寻址和直接寻址占有重要成分,立即寻址用于计算,直接寻址用于函数调用和跳转。
    然后是内存操作。 取到内存数据。

你可能感兴趣的:(c,优化,String,X86)