深入函数调用堆栈--------具体过程详解

通过下面的简单的程序来理解一下函数在调用过程中具体都干了什么:

首先我们先来了解一些简单的指令:

mov      用来移内存的值                              lea       移地址                                      push        从栈顶入栈

pop       从栈顶出栈                                    rep    stos          循环拷贝                      sub    a,b    a-b之后赋给a

简单的汇编过程如下:

int main()

{

    push      ebp

    move    ebp   esp

     sub       esp   0xch

     rep   stos--->ebp<---->esp

此段代码为每个函数开始前都会有的固定代码,具体作用见上篇博文

int  a=10;

     mov       dword ptr[ebp -4]  ,10

int b=20;

    mov        dword ptr[ebp - 8]  ,14h

int ret = 0;

    mov        dword  ptr[ebp - 0ch] , 0

ret = sum(a,b);

    mov    eax,dword ptr[ebp-8]

    push    eax

    mov     ecx,dword ptr[ebp-4]

    call       sum;------跳转,将下一行指令的地址入栈(下一行指令的地址通过后面的ret得到)

    add       esp,8-----回退形参变量的栈内存

    mov      dword ptr[ebp-0ch],eax

}

int sum(int a,int b)

{

//固定代码,同上

int temp = 0;

    mov    dword ptr[ebp-4],0

temp = a+b;

    mov     eax,dword ptr[ebp+8]

    add      eax,dword ptr[ebp+0ch]

    mov      dword ptr[ebp-4],eax

return temp;

    mov      eax,dword ptr[ebp-4]

}

    mov      esp,ebp

    pop       ebp----出栈,并把出栈元素赋给ebp

    ret -------出栈,栈顶元素赋给CPU  PC寄存器(PC寄存器永远存放下一行指令的地址,放那个指令的地址,就运行那个指令)

用内存图可表示如下:


注:栈内存上定义的变量在未进行初始化时是一个无效值,不是随机值 

猜你喜欢

转载自blog.csdn.net/m0_37962600/article/details/79833614