C++——函数调用堆栈

来源:互联网 发布:foxit editor mac 编辑:程序博客网 时间:2024/06/11 09:17

汇编分为两种:

  1.inter x86:从右往左

  2.AT&T unix:从左往右

函数调用堆栈

源代码:

反汇编代码:


ebp:栈底指针  esp:栈顶指针,在栈上开辟内存,通过ebp指针的偏移量来访问数据

10: int a = 10;

002E143E mov        dword ptr [ebp-8],0Ah  ,将a入栈,

   11: int b = 20;

002E1445 mov        dword ptr [ebp-14h],14h  ,将b入栈

   12: int ret = 0;

002E144C mov        dword ptr [ebp-20h],0  ,将ret入栈

 压栈

 调用函数:

     1.压入形参变量的地址和值,

     2.压入函数调用返回后要执行的指令的地址

 被调用函数:

     1.压入调用函数的栈底指针,把栈底指针寄存器指向被调用函数的栈底

     2.开辟被调用函数的栈帧大小,并初始化为CC


 清栈

 被调用函数

     1.清理被调用函数开辟的栈帧大小

     2.回退栈底指针到调用函数的栈底

     3.把回退到调用函数要执行的指令地址给pc寄存器

 调用函数:

      1.清理形参变量的内存


2.函数的返回值

  1.4 eax 

  2.8 eax edx

  3.>8开辟一个临时量(调用方函数栈帧)

   eax 带出临时量的地址

   循环拷贝到接收返回值的变量的地址空间


3.函数的调用约定

_cdecl c的调用约定

 

_stdcall Windows下的标准调用约定

_fastcall快速调用约定

 

_thiscall C++的成员函数调用约定

 

三种调用约定的区别:

1.符号的生成方式

ld合并符号表

 main:符号表 _cdecl   ?sum@@YAHHH@Z *UND* gobal

  符号解析   

 test:       _stdcall ?sum@@YGHHH@Z .text gobal

              _fastcall ?sum@@YIHHH@Z

2.参数的压栈方式

3.函数的形参清理

       _cdecl 调用方开辟 调用方清理

       _stdcall调用方开辟 被调用方清理

       _fastcall

        <= 8 

        寄存器带值  不需要形参变量的清理

        > 8

        2个形参寄存器带值  不需要形参变量的清理

        后面的和stdcall调用方式一样






原创粉丝点击