简单的C程序 汇编分析

时间:2023-01-03 00:56:32

简单的C程序 汇编分析

//源代码

typedef struct

{

   int i;

   char c;

}S;

int fun(int i, char c, S * s)

{

   s->i = i;

   s->c = c;

   return 0;

}

int main()

{

   S s;

   fun(1, 'C', &s);

   return 0;

}

//汇编分析

main 函数

堆栈(注:栈的增长方向 从大到小 4字节对齐)

栈顶

...

s.i ← 变量s的地址 [ebp-8]

s.c

ebp

...

栈底

14:   int main()

15:   {

00401060   push        ebp

00401061   mov         ebp,esp

00401063   sub         esp,48h

00401066   push        ebx

00401067   push        esi

00401068   push        edi

00401069   lea         edi,[ebp-48h]

0040106C   mov         ecx,12h

00401071   mov         eax,0CCCCCCCCh

00401076   rep stos    dword ptr [edi]

16:       S s;

17:       fun(1, 'C', &s);           //函数调用过程 从右到左压栈

00401078   lea         eax,[ebp-8]      

0040107B   push        eax                //s的地址入栈

0040107C   push        43h               //参数'C'入栈

0040107E   push        1                //参数1入栈 

00401080   call        @ILT+0(_fun) (00401005)   //调用fun函数

00401085   add         esp,0Ch         

18:       return 0;

00401088   xor         eax,eax        //返回值 存在eax中

19:   }

0040108A   pop         edi

0040108B   pop         esi

0040108C   pop         ebx

0040108D   add         esp,48h

00401090   cmp         ebp,esp

00401092   call        __chkesp (004010b0)

00401097   mov         esp,ebp

00401099   pop         ebp

0040109A   ret

Main函数 将参数压栈后 通过 call 00401005 调用fun 函数

00401005   jmp         fun (00401020)   //00401020是fun函数的入口地址

fun 函数

堆栈:

栈顶

...

ebp

eip

i ← 参数i: ebp+8

c ← 参数c: ebp+0C

&s ← 参数s的地址: ebp+10

...

栈底

7:    int fun(int i, char c, S * s)

8:    {

00401020   push        ebp

00401021   mov         ebp,esp

00401023   sub         esp,40h

00401026   push        ebx

00401027   push        esi

00401028   push        edi

00401029   lea         edi,[ebp-40h]

0040102C   mov         ecx,10h

00401031   mov         eax,0CCCCCCCCh

00401036   rep stos    dword ptr [edi]

9:        s->i = i;

00401038   mov         eax,dword ptr [ebp+10h]   //s的地址 → eax

0040103B   mov         ecx,dword ptr [ebp+8]    // i → ecx

0040103E   mov         dword ptr [eax],ecx     // ecx → [eax]: s->i = i

10:       s->c = c;

00401040   mov         edx,dword ptr [ebp+10h] //s的地址 → eax

00401043   mov         al,byte ptr [ebp+0Ch]  //c → al  char 占一个字节

00401046   mov         byte ptr [edx+4],al   // al → [edx+4]: s->c = c

11:       return 0;

00401049   xor         eax,eax

12:   }

0040104B   pop         edi

0040104C   pop         esi

0040104D   pop         ebx

0040104E   mov         esp,ebp

00401050   pop         ebp

00401051   ret