循环~跳转表

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Z_J_T/article/details/78859076

1、

空语句:只包含一个分号的语句。

2、

if 语句,for 语句,while,do while()
for 语句:适用于已知循环次数,for循环一般都有输出执行语句,除非定义的循环初始条件满足退出条件,直接退出循环。

while():适用于未知循环次数,while()加循环条件,一但条件不满足就不执行语句。

do while():适合于循环至少执行一次的,先执行后判断。do while()判断条件满足则执行语句,条件不满足时退出循环.

都可以执行死循环
do{}while(1);
for(;1;);
while(1);

3、if语句和switch语句反汇编

if语句

int i = 3;
009B178E  mov         dword ptr [i],3  
    if (i == 1)
009B1795  cmp         dword ptr [i],1  
009B1799  jne         main+3Ah (09B17AAh)  
    {
        printf("one\n");
009B179B  push        offset string "one\n" (09B6BD0h)  
009B17A0  call        _printf (09B1316h)  
009B17A5  add         esp,4  
009B17A8  jmp         main+71h (09B17E1h)  
    }
    else if (i == 2)
009B17AA  cmp         dword ptr [i],2  
009B17AE  jne         main+4Fh (09B17BFh)  
    {
        printf("two\n");
009B17B0  push        offset string "two\n" (09B6BD8h)  
009B17B5  call        _printf (09B1316h)  
009B17BA  add         esp,4  
009B17BD  jmp         main+71h (09B17E1h)  
    }
    else if (i == 3)
009B17BF  cmp         dword ptr [i],3  
009B17C3  jne         main+64h (09B17D4h)  
    {
        printf("three\n");
009B17C5  push        offset string "three\n" (09B6BE0h)  
009B17CA  call        _printf (09B1316h)  
009B17CF  add         esp,4  
    }
    else
009B17D2  jmp         main+71h (09B17E1h)  
    {
        printf("foure\n");
009B17D4  push        offset string "foure\n" (09B6BE8h)  
    {
        printf("foure\n");
009B17D9  call        _printf (09B1316h)  
009B17DE  add         esp,4  
    }

何为 switch 的跳转表???

只有超过3条case语句(等于3不会)才会形成跳转表

假设
switch(j)
地址
case1 :010A4E26
case3 :010A4E35
caes6 :010A4E44
case8 :010A4E53
return :010A4E60

j-1和8-1比较 大于 直接跳到return
小于或等于在调转表中查找(j-1)*4+0x010A4E78

跳转表–>内存
这里写图片描述

在跳转表中 首地址(0x010A4E78)
当j=1时,(1-1)*4+0x010A4E78 存放case1(j=1)地址(010A4E26)
当j=2时,(2-1)*4+0x010A4E78 存放return的地址
当j=3时,(3-1)*4+0x010A4E78 存放case3(j=3)地址(010A4E35)

由此可知,跳转表当case后的常量不连续,且case总数大于3,所创建的跳转表,(j-1)*4+0x010A4E78地址下,存在的用所对应的地址填充,不存在填充return地址。

具体事例

switch (j)
009A4DF8  mov         eax,dword ptr [j]  
009A4DFB  mov         dword ptr [ebp-0DCh],eax  
009A4E01  mov         ecx,dword ptr [ebp-0DCh]  
009A4E07  sub         ecx,1  
009A4E0A  mov         dword ptr [ebp-0DCh],ecx  
009A4E10  cmp         dword ptr [ebp-0DCh],5(最后一个case的值-1)  
009A4E17  ja          $LN13+0Dh (09A4E60h)  
009A4E19  mov         edx,dword ptr [ebp-0DCh]  
009A4E1F  jmp         dword ptr [edx*4+9A4E78h]  

跳转表
这里写图片描述

{
    case 1:
        printf("one\n");
009A4E26  push        offset string "one\n" (09A6BD0h)  
009A4E2B  call        _printf (09A1316h)  
009A4E30  add         esp,4  
        break;
009A4E33  jmp         $LN13+0Dh (09A4E60h)  
    case 2:
        printf("fdfd\n");
009A4E35  push        offset string "fdfd\n" (09A6CD0h)  
009A4E3A  call        _printf (09A1316h)  
009A4E3F  add         esp,4  
        break;
009A4E42  jmp         $LN13+0Dh (09A4E60h)  
    case 3:
        printf("oddsne\n");
009A4E44  push        offset string "oddsne\n" (09A6CD8h)  
009A4E49  call        _printf (09A1316h)  
009A4E4E  add         esp,4  
        break;
009A4E51  jmp         $LN13+0Dh (09A4E60h)  
    case 6:
        printf("odddddddsne\n");
009A4E53  push        offset string "odddddddsne\n" (09A6CE0h)  
009A4E58  call        _printf (09A1316h)  
009A4E5D  add         esp,4  
default:
            break;
        }
    return 0;
009A4E60  xor         eax,eax  
}

猜你喜欢

转载自blog.csdn.net/Z_J_T/article/details/78859076