栈帧的概念以及图示

文章目录

1 栈帧(Stack Frame)

每个函数的每次调用都会产生一个栈帧,用来记录函数的执行过程。eg:在C语言编译为汇编语言时,每个函数的第一句永远都是

	pushl	%ebp  !保存上一个函数的栈基址
	movl	%esp, %ebp !初始化本次函数调用的栈

当函数funcA调用funcB时,栈的变化如下

void funcA(){
    funcB(x,y);
}
void funcB(x,y){
	do_sth(x,y);
}
  1. funcA把funcB所需的参数以从右向左←的方向压入栈中
  2. funcA执行汇编指令call funcB,并且把返回地址压入栈中,这里是把"{"压入了栈中。
  3. funcB开始执行,首选保存funcA的栈基址pushl ebp,然后用mov esp,ebp指令开启新的属于funcB的栈
  4. 在funcB中,依照定义的次序依次压入局部变量
  5. 在funcB中,通过ebp + 4,ebp + 8…ebp + 4n的方式来获得传递给funcB的第n个参数,通过ebp - 4,ebp - 8…ebp - 4n的方式来获得第n个局部变量
  6. 注意,栈的方向是从高地址到低地址的。
    在这里插入图片描述

以下面的代码为例来描述栈帧的变化过程

void main(){
	int res;
	res = sum(3,4);
}
int sum(int x,int y){
    int z;
    z = x + y;
    return z;
}

在32位系统上用gcc -S命令编译成汇编代码如下(会改变栈的命令用!标出)

        .file   "sum.c"
gcc_compiled.:
.tex?
        .align 2
.globl _sum
_sum:
        pushl %ebp (6)
        movl %esp,%ebp !(7)
        subl $4,%esp !(8)
        movl 8(%ebp),%edx
        addl 12(%ebp),%edx
        movl %edx,-4(%ebp)
        movl -4(%ebp),%eax
        jmp L1
        .align 2
L1:
        leave !(9,10)
        ret !(11)
        .align 2
.globl _main
_main:
        pushl %ebp !(1)
        movl %esp,%ebp !(2) 
        subl $4,%esp !(3)
        pushl $4 !(4)
        pushl $3 !(4)
        call _sum !(5)
        movl %eax,-4(%ebp)
L2:
        leave
        ret

栈的变化情况如下

注:

  1. pushl eax的解释esp = esp - 4,*(esp) = ax,先改变栈顶,再存入数据
  2. popl eax的解释*(esp) = ax,esp = esp + 4先改变栈顶,再存入数据
  3. 下面的两种表示方法是等价的,第一个更规范,但是注意方向。
    在这里插入图片描述

  1. 进入main,执行pushl %ebp
    在这里插入图片描述

  2. 执行movl %esp,%ebp在这里插入图片描述

  3. 执行subl $4,%esp在这里插入图片描述

  4. pushl $4 pushl $3在这里插入图片描述

  5. call _sum在这里插入图片描述

  6. push %ebp在这里插入图片描述

  7. mov %esp,%ebp在这里插入图片描述

  8. sub $4,%esp
    在这里插入图片描述

  9. leave
    在这里插入图片描述

  10. leave
    在这里插入图片描述

  11. ret
    在这里插入图片描述

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值