C到汇编[1]

这篇文字解释这个问题:C语言函数调用在汇编语言是怎么实现的?栈模型很好的满足了函数调用的需求,以最简单的函数调用说明。

 1 5:    int add2(int a, int b){return a+b;}
 2 0040B450   push        ebp
 3 0040B451   mov         ebp,esp
 4 0040B453   sub         esp,40h
 5 0040B456   push        ebx
 6 0040B457   push        esi
 7 0040B458   push        edi
 8 0040B459   lea         edi,[ebp-40h]
 9 0040B45C   mov         ecx,10h
10 0040B461   mov         eax,0CCCCCCCCh
11 0040B466   rep stos    dword ptr [edi]
12 0040B468   mov         eax,dword ptr [ebp+8]
13 0040B46B   add         eax,dword ptr [ebp+0Ch]
14 0040B46E   pop         edi
15 0040B46F   pop         esi
16 0040B470   pop         ebx
17 0040B471   mov         esp,ebp
18 0040B473   pop         ebp
19 0040B474   ret
20 
21 --- No source file  ---------------------------------------------------------------------------------------------------------------------------------------
22 0040B76C   int         3
23 0040B76D   int         3
24 0040B76E   int         3
25 0040B76F   int         3
26 --- e:项目00test	estconsolemain.cpp  -----------------------------------------------------------------------------------------------------------------
27 6:
28 7:    int main(int argc, char **argv){
29 0040B770   push        ebp
30 0040B771   mov         ebp,esp
31 0040B773   sub         esp,4Ch
32 0040B776   push        ebx
33 0040B777   push        esi
34 0040B778   push        edi
35 0040B779   lea         edi,[ebp-4Ch]
36 0040B77C   mov         ecx,13h
37 0040B781   mov         eax,0CCCCCCCCh
38 0040B786   rep stos    dword ptr [edi]
39 8:
40 9:        int a = 10;
41 0040B788   mov         dword ptr [ebp-4],0Ah
42 10:       int b = 20;
43 0040B78F   mov         dword ptr [ebp-8],14h
44 11:       int c = add2(a, b);
45 0040B796   mov         eax,dword ptr [ebp-8]
46 0040B799   push        eax
47 0040B79A   mov         ecx,dword ptr [ebp-4]
48 0040B79D   push        ecx
49 0040B79E   call        @ILT+5(add2) (0040100a)
50 0040B7A3   add         esp,8
51 0040B7A6   mov         dword ptr [ebp-0Ch],eax
52 12:
53 13:       return c;
54 0040B7A9   mov         eax,dword ptr [ebp-0Ch]
55 14:   }
56 0040B7AC   pop         edi
57 0040B7AD   pop         esi
58 0040B7AE   pop         ebx
59 0040B7AF   add         esp,4Ch
60 0040B7B2   cmp         ebp,esp
61 0040B7B4   call        __chkesp (0040b6b0)
62 0040B7B9   mov         esp,ebp
63 0040B7BB   pop         ebp
64 0040B7BC   ret

44行执行函数调用,过程如下:

(1)参数入栈,从右向左;

(2)CALL指令,注意CALL指令将EIP入栈,并JMP;

(3)初始化ADD函数堆栈,push ebp; mov ebp, esp;sub esp,0x40; push ebx; push esi; push edi; rep stos ptr dword es:[edi].  rep指令表示,执行循环,循环次数放置在ECX寄存器中;stos指令表示,将EAX值放入edi指向的地址,并将edi递增.  在第10行我们看到EAX被设置为0xCCCCCCCC,所以rep stos ptr dword es:[edi]的作用是,将开辟的0x40局部变量空间初始化为0xCC,0xCC是INT 3的汇编指令,目的是防止误执行。

(4)执行ADD指令,结果存放在EAX中;

(5)恢复现场,pop ebx; pop esi; pop edi;

(6)ret,弹出eip;

(7)保持栈平衡,add esp,8;

image

原文地址:https://www.cnblogs.com/yuqiao-ray-vision/p/3754448.html