函数栈详解

函数栈

这篇文章会详细的讨论:在程序中调用函数时,具体的栈中数据会如何变化。
文章基于64位,所以ebp->rbp、esp->rsp

c代码

#include <stdio.h>

void add(int *x, int *y){
    *x = 10;
    *y = 10;
}

int main(){
    int m, n=0;
    add(&m, &n);
    printf("%d %d", m, n);

    return 0;
}

反汇编代码

Dump of assembler code for function main():
8	int main(){
   0x0000000000401573 <+0>:	push   %rbp     //将基指针的值rbp压入栈中,保存当前的栈帧基址
   0x0000000000401574 <+1>:	mov    %rsp,%rbp  //创建新的栈帧
   0x0000000000401577 <+4>:	sub    $0x30,%rsp   //在栈上为局部变量和保存的寄存器留出空间
   0x000000000040157b <+8>:	callq  0x401670 <__main>

9	int m, n=0;
=> 0x0000000000401580 <+13>:	movl   $0x0,-0x8(%rbp)   将变量n的值(0)存储在栈上的某个位置(%rbp-0x8)

10 add(&m, &n);
   0x0000000000401587 <+20>:	lea    -0x8(%rbp),%rdx
   0x000000000040158b <+24>:	lea    -0x4(%rbp),%rax  //加载变量m和n的地址到寄存器%rdx和%rax。
   0x000000000040158f <+28>:	mov    %rax,%rcx        //将%rax的值复制到%rcx,这是为了将m的地址作为第一个参数传递给函数add。
   0x0000000000401592 <+31>:	callq  0x401550 <add(int*, int*)>

11 printf("%d %d", m, n);
   0x0000000000401597 <+36>:	mov    -0x8(%rbp),%edx  //从栈中加载m和n的值到寄存器%edx和%eax
   0x000000000040159a <+39>:	mov    -0x4(%rbp),%eax
   0x000000000040159d <+42>:	mov    %edx,%r8d
   0x00000000004015a0 <+45>:	mov    %eax,%edx
   0x00000000004015a2 <+47>:	lea    0x2a57(%rip),%rcx        # 0x404000
   0x00000000004015a9 <+54>:	callq  0x402aa0 <printf>

12	
13 return 0;
   0x00000000004015ae <+59>:	mov    $0x0,%eax

14	}
   0x00000000004015b3 <+64>:	add    $0x30,%rsp
   0x00000000004015b7 <+68>:	pop    %rbp
   0x00000000004015b8 <+69>:	retq 

Dump of assembler code for function add(int*, int*):
3	void add(int *x, int *y){
   0x0000000000401550 <+0>:	push   %rbp
   0x0000000000401551 <+1>:	mov    %rsp,%rbp
   0x0000000000401554 <+4>:	mov    %rcx,0x10(%rbp)
   0x0000000000401558 <+8>:	mov    %rdx,0x18(%rbp)

4	    *x = 10;
=> 0x000000000040155c <+12>:	mov    0x10(%rbp),%rax
   0x0000000000401560 <+16>:	movl   $0xa,(%rax)

5	    *y = 10;
   0x0000000000401566 <+22>:	mov    0x18(%rbp),%rax
   0x000000000040156a <+26>:	movl   $0xa,(%rax)

6	}
   0x0000000000401570 <+32>:	nop
   0x0000000000401571 <+33>:	pop    %rbp
   0x0000000000401572 <+34>:	retq   

End of assembler dump.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值