汇编学习笔记:函数调用过程中的堆栈分析

这篇博客通过一个简单的C程序,深入剖析了函数调用过程中汇编代码的堆栈变化。从C程序源码到汇编代码,详细解释了call、ret指令以及push、pop指令如何影响堆栈,特别是如何处理参数传递和返回值。此外,还讨论了enter和leave指令在构建和恢复函数堆栈中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原创作品:陈晓爽(cxsmarkchan)
转载请注明出处
《Linux操作系统分析》MOOC课程 学习笔记

本文通过汇编一段含有简单函数调用的C程序,说明在函数调用过程中堆栈的变化。

1 C程序及其汇编代码

1.1 C程序源码

本文使用的C程序源码如下:

//main.c
int g(int x){
    return x + 5;
}

int f(int x){
    return g(x);
}

int main(void){
    return f(9) + 3;
}

这个程序仅含有main函数和两个函数调用,不含输入输出。不难看出程序的运行过程为:
- main函数调用f函数,传入参数9;
- f函数调用g函数,传入参数9;
- g函数返回9+5,即14;
- f函数返回14;
- main函数返回14+3,即17.

1.2 汇编代码

在linux(本文平台为实验楼Linux内核分析)下执行如下编译指令:

gcc -S -o main.s main.c -m32

该指令可将main.c编译为汇编代码(而非二进制执行文件),输出到main.s。参数“-m32”表示采用32位的方式编译。

用vim打开main.s文件,可以看到如下图的汇编代码:

原始汇编代码

在main.s中,有大量的以“.”开头的行,这些行只是用于链接的说明性代码,在实际的程序中并不会出现。为便于分析,可以将这些内容删去,得到纯粹的汇编代码,如下:

g:
02  pushl %ebp
03  movl %esp, %ebp
04  movl 8(%ebp), %eax
05  addl $5, %eax
06  popl %ebp
07  ret
f:
09  pushl %ebp
10  movl %esp, %ebp
11  subl $4, %esp
12  movl 8(%ebp), %eax
13  movl %eax, (%esp)
14  call g
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值