码迷,mamicode.com
首页 > 其他好文 > 详细

函数调用栈维护过程

时间:2020-05-07 00:26:08      阅读:72      评论:0      收藏:0      [点我收藏+]

标签:int   bsp   表示   ddl   city   恢复   pow   char   inf   

涉及到以下汇编指令:

pushl: 入栈

ebp指向栈底 esp指向栈顶

入栈时只需要将esp下移, 将入栈的值放入esp指向的地址,如下图所示:

技术图片

popl: 出栈

先将栈顶的数据保存,再将esp上移

技术图片

call:顾名思义,调用一个函数

调用一个函数需要将当前执行到的指令位置(eip寄存器的值)保存,也就是使用pushl指令入栈。再将eip寄存器的值置为要跳转的地址。

技术图片

ret: 结束当前函数

恢复上个函数的执行位置,也就是将esp指向的地址保存至eip,再将esp上移。

技术图片

观察以下代码生成的汇编语言:

#include <iostream>

using namespace std;

int power(int x)
{
        return x*x;
}

int main()
{
        int res = power(3);

        cout << res <<endl;

        return 0;
}

g++ -S test.cpp -o test.S

得到生成的汇编代码:

_Z5poweri:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %eax
        imull   8(%ebp), %eax
        popl    %ebp
        ret
main:
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ecx
        subl    $20, %esp
        pushl   $3
        call    _Z5poweri
        addl    $4, %esp
        movl    %eax, -12(%ebp)
        subl    $8, %esp
        pushl   -12(%ebp)
        pushl   $_ZSt4cout
        call    _ZNSolsEi
        addl    $16, %esp
        subl    $8, %esp
        pushl   $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
        pushl   %eax
        call    _ZNSolsEPFRSoS_E
        addl    $16, %esp
        movl    $0, %eax
        movl    -4(%ebp), %ecx
        leave
        leal    -4(%ecx), %esp
        ret

power函数名经过name-mangling转化为_Z5poweri,_是开始标志,5是函数名长度,i表示返回值为int。

调用power函数的流程如下:

main函数先将函数参数保存,再调用call指令调用power函数,保存eip的值。就有了下图的第一个状态。

技术图片

 

函数调用栈维护过程

标签:int   bsp   表示   ddl   city   恢复   pow   char   inf   

原文地址:https://www.cnblogs.com/HadesBlog/p/12839866.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!