Windowsx86内核(二)

C语言的流程和处理

程序分为Dubug版与Release(发行版)
调试版一般不优化,Release会优化代码,即减去没必要的汇编部分。

一、C语言的循环汇编

1.for循环
测试代码:

for (i = 0; i < 5; i++)
    {
        c = c + 1;
    }

查看反汇编:

    for (i = 0; i < 5; i++)
00164464  mov         dword ptr [i],0  
0016446B  jmp         main+46h (0164476h)  
0016446D  mov         eax,dword ptr [i]  
00164470  add         eax,1  
00164473  mov         dword ptr [i],eax  
00164476  cmp         dword ptr [i],5  
0016447A  jge         main+57h (0164487h)  
    {
        c = c + 1;
0016447C  mov         eax,dword ptr [c]  
0016447F  add         eax,1  
00164482  mov         dword ptr [c],eax  
    }
00164485  jmp         main+3Dh (016446Dh)

大致是这样的结构:

mov <循环变量>,<初始值>          ;给循环变量赋值
jmp B                         ;跳到第一个循环处
A:  (改动循环变量)             ;修改循环变量
   ...
B:  cmp <循环变量>,<限制变量>    ;检查循环条件
    jge 跳出循环                
    (循环体)
    ...
    jmp A                     ;跳回去修改循环变量

2.while
测试代码:

while (c < 100){
        c = c + 1;
    }

查看反汇编:

while (c < 100){
00AC4464  cmp         dword ptr [c],64h  
00AC4468  jge         main+45h (0AC4475h)  
        c = c + 1;
00AC446A  mov         eax,dword ptr [c]  
00AC446D  add         eax,1  
00AC4470  mov         dword ptr [c],eax  
    }
00AC4473  jmp         main+34h (0AC4464h) 

共有3条指令实现:

A: cmp <循环变量>,<限制变量>
    jge B
    ...
    jmp A
B:  循环结束,下一个指令

3.do-while
测试代码:

do {
        c = c + 1;
    } while (c < 100);

查看反汇编:

do {
        c = c + 1;
00E14464  mov         eax,dword ptr [c]  
00E14467  add         eax,1  
00E1446A  mov         dword ptr [c],eax  
    } while (c < 100);
00E1446D  cmp         dword ptr [c],64h  
00E14471  jl          main+34h (0E14464h)  

do循环就是用一个简单的条件比较指令跳转回去。只有两个指令。

cmp <循环变量>,<限制变量>
jl  <循环开始点>

二、C语言的判断与选择

1.if-else
源码:

int main()
{
    int c = 1;
    if (c > 0 &&c < 10)
    {
        printf("c>0\n");
    }
    else if (c>10 && c < 100)
    {
        printf("c>10%%c<100\n");
    }
    else {
        printf("c>100||c<0");
    }

    return 0;
}

主要代码为:
cmp <条件>
jle <下一个分支>

开始的反汇编:

int c = 1;
00C3538E  mov         dword ptr [c],1  
if (c > 0 &&c < 10)
00C35395  cmp         dword ptr [c],0  
00C35399  jle         main+4Ah (0C353BAh)  
00C3539B  cmp         dword ptr [c],0Ah  
00C3539F  jge         main+4Ah (0C353BAh)  
{
        printf("c>0\n");
00C353A1  mov         esi,esp  
00C353A3  push        0C3CC84h  
00C353A8  call        dword ptr ds:[0C40188h]  
00C353AE  add         esp,4  
00C353B1  cmp         esi,esp  
00C353B3  call        __RTC_CheckEsp (0C312DAh)  
00C353B8  jmp         main+86h (0C353F6h)  
    }

大致都是这样的:

else if (c>10 && c < 100)
00C353BA  cmp         dword ptr [c],0Ah  
00C353BE  jle         main+6Fh (0C353DFh)  
00C353C0  cmp         dword ptr [c],64h  
00C353C4  jge         main+6Fh (0C353DFh)  

2.switch-case

代码:

int c = 1;
    switch (c)
    {
    case 0:
        printf("c>0");
    case 1:
    {
              printf("c>10&c<100");
              break;
    }
    default:
        printf("cccc");
    }

看反汇编:
这里写图片描述
连续的比较与条件跳转让人想到switch。

至于case和default都非常简单。如果有break,则会增加一个无条件跳转:在没有break的情况下,没有任何流程控制代码。
这里写图片描述

三、C语言的数组与结构

写一个简单的结构体和数组。
测试代码:

typedef struct {
    int a;
    int b;
    int c;
}mystruct;
int main()
{
    unsigned char *buf[100];
    mystruct *strs = (mystruct *)buf;
    int i;
    for (i = 0; i < 5; i++)
    {
        strs[i].a = 0;
        strs[i].b = 1;
        strs[i].c = 2;
    }
    return 0;
}

看反汇编:

int i;
    for (i = 0; i < 5; i++)
00AB4614  mov         dword ptr [i],0        ;典型的for循环结构
00AB461E  jmp         main+4Fh (0AB462Fh)  
00AB4620  mov         eax,dword ptr [i]  
00AB4626  add         eax,1  
00AB4629  mov         dword ptr [i],eax  
00AB462F  cmp         dword ptr [i],5  
00AB4636  jge         main+98h (0AB4678h)  
    {
        strs[i].a = 0;
00AB4638  imul        eax,dword ptr [i],0Ch  ;吧i*0c放入到eax中
                                             ;0ch是结构体的大小
00AB463F  mov         ecx,dword ptr [strs]   ;ecx为strs的首地址
00AB4645  mov         dword ptr [ecx+eax],0  ;给首地址+i*0c赋值为0
        strs[i].b = 1;
00AB464C  imul        eax,dword ptr [i],0Ch  
00AB4653  mov         ecx,dword ptr [strs]  
00AB4659  mov         dword ptr [ecx+eax+4],1 ;给首地址+i*0c+4赋值为1
        strs[i].c = 2;
00AB4661  imul        eax,dword ptr [i],0Ch  
00AB4668  mov         ecx,dword ptr [strs]  
00AB466E  mov         dword ptr [ecx+eax+8],2 ;给首地址+i*0c+8赋值为2
    }
00AB4676  jmp         main+40h (0AB4620h)  
    return 0;
00AB4678  xor         eax,eax 

imul指令让人联想到结构体数组,这是一个特征。

四、C语言的共用体和枚举类型

//定义一个枚举类型
typedef enum{
    ENUM_1 = 1,
    ENUM_2 = 2,
    ENUM_3,
    ENUM_4,
}myebum;
//定义一个结构体
typedef struct {
    int a;
    int b;
    int c;
}mystruct;

typedef union {
    mystruct s;
    myebum e[3];
}myunion;
int main()
{
    unsigned char *buf[100];
    myunion *uns = (myunion *)buf;
    int i;
    for (i = 0; i < 5; i++)
    {
        uns[i].s.a = 0;
        uns[i].s.b = 1;
        uns[i].e[2] = ENUM_4;
    }
    return 0;
}
myunion *uns = (myunion *)buf;
00034608  lea         eax,[buf]  
0003460E  mov         dword ptr [uns],eax  
    int i;
    for (i = 0; i < 5; i++)
00034614  mov         dword ptr [i],0  
0003461E  jmp         main+4Fh (03462Fh)  
00034620  mov         eax,dword ptr [i]  
00034626  add         eax,1  
00034629  mov         dword ptr [i],eax  
0003462F  cmp         dword ptr [i],5  
00034636  jge         main+9Eh (03467Eh)  
    {
        uns[i].s.a = 0;
00034638  imul        eax,dword ptr [i],0Ch  
0003463F  mov         ecx,dword ptr [uns]  
00034645  mov         dword ptr [ecx+eax],0  
        uns[i].s.b = 1;
0003464C  imul        eax,dword ptr [i],0Ch  
        uns[i].s.b = 1;
00034653  mov         ecx,dword ptr [uns]  
00034659  mov         dword ptr [ecx+eax+4],1  
        uns[i].e[2] = ENUM_4;
00034661  imul        eax,dword ptr [i],0Ch  
00034668  add         eax,dword ptr [uns]  
0003466E  mov         ecx,4  
00034673  shl         ecx,1  
00034675  mov         dword ptr [eax+ecx],4  
    }
0003467C  jmp         main+40h (034620h)  
    return 0;
0003467E  xor         eax,eax  

对比结构体基本没有什么区别。
对于编译器处理来说,它们并不引入额外的指令。

猜你喜欢

转载自blog.csdn.net/qq_35495684/article/details/79861396
86