2025年c语言函数的调用过程分析

c语言函数的调用过程分析一 函数的调用过程 首先我们再 viso studio 中编写如下代码 int add int a int b int c a b return c int main int d d add 1 2 printf d d r n d

大家好,我是讯享网,很高兴认识大家。

一、函数的调用过程

首先我们再viso studio中编写如下代码:

int add(int a, int b) { int c = a + b; return c; } int main() { int d; d = add(1,2); printf("d=%d\r\n",d); } 

讯享网

反汇编后得到如下汇编代码:

讯享网int add(int a, int b) { //入栈保护现场 00B117A0 push ebp 00B117A1 mov ebp,esp 00B117A3 sub esp,0CCh 00B117A9 push ebx 00B117AA push esi 00B117AB push edi 00B117AC lea edi,[ebp-0CCh] 00B117B2 mov ecx,33h 00B117B7 mov eax,0CCCCCCCCh 00B117BC rep stos dword ptr es:[edi] 00B117BE mov ecx,offset _549F54B0_consoleapplication1@cpp (0B1C008h) 00B117C3 call @__CheckForDebuggerJustMyCode@4 (0B1120Dh) int c = a + b; 00B117C8 mov eax,dword ptr [a] 00B117CB add eax,dword ptr [b] int c = a + b; 00B117CE mov dword ptr [c],eax return c; 00B117D1 mov eax,dword ptr [c] } //add调用结束,出栈恢复现场 00B117D4 pop edi 00B117D5 pop esi 00B117D6 pop ebx 00B117D7 add esp,0CCh //回复sp指针,释放局部变量占用的内存 00B117DD cmp ebp,esp 00B117DF call __RTC_CheckEsp (0B11217h) 00B117E4 mov esp,ebp 00B117E6 pop ebp 00B117E7 ret int main() { 00CC1930 push ebp //基址指针寄存器 00CC1931 mov ebp,esp //保存当前堆栈,将栈顶指针存入ebp,当前栈顶和栈低重合 00CC1933 sub esp,0CCh //栈顶指针向下偏移0xccbyte,开辟临时变量的空间(栈空间) 00CC1939 push ebx 00CC193A push esi 00CC193B push edi 00CC193C lea edi,[ebp-0CCh] 00CC1942 mov ecx,33h 00CC1947 mov eax,0CCCCCCCCh 00CC194C rep stos dword ptr es:[edi] 00CC194E mov ecx,offset _549F54B0_consoleapplication1@cpp (0CCC008h) 00CC1953 call @__CheckForDebuggerJustMyCode@4 (0CC1221h) int d; d = add(1,2); //从这里可以看出来,函数参数的入栈方向是自有向左 00CC1958 push 2 //最右边的形参入栈 00CC195A push 1 //最左边的形参入栈 00CC195C call add (0CC1186h) 00CC1961 add esp,8 00CC1964 mov dword ptr [d],eax printf("d=%d\r\n",d); 00CC1967 mov eax,dword ptr [d] 00CC196A push eax 00CC196B push offset string "d=%d\r\n" (0CC7B30h) 00CC1970 call _printf (0CC104Bh) 00CC1975 add esp,8 } //main函数调用结束,恢复现场 00CC1978 xor eax,eax 00CC197A pop edi 00CC197B pop esi 00CC197C pop ebx 00CC197D add esp,0CCh 00CC1983 cmp ebp,esp 00CC1985 call __RTC_CheckEsp (0CC122Bh) 00CC198A mov esp,ebp 00CC198C pop ebp 00CC198D ret 

寄存器知识讲解

X86/64 vc++的堆栈是从高地址向低地址生长,比如push一个32位寄存器入栈后,esp - 04H。


讯享网

汇编指令讲解

sub 减计数器sub esp,04h表示将栈顶指针向下移动4个字节

总结

从上述C语言代码的反汇编来看,函数在调用的时候会对add的两个参数进行入栈操作,因此函数的形参也是需要占用栈空间的,只是形式参数占用的空间在函数调用结束后会自动释放。

函数的调用其实就是一个入栈和出栈的过程,在函数调用前调用push保护现场,在函数调用结束后调用pop恢复现场,并将sp指针恢复为函数调用前的状态,释放调用函数所占用的内存空间。

小讯
上一篇 2025-03-04 17:42
下一篇 2025-03-13 16:39

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/13753.html