首先给出完整的C代码:
int g(int x)
{
return x+11;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(8)+1;
}
使用命令:gcc –S –o hw001.s hw001.c -m32
对应生成的IA32汇编代码如图所示:
暂不分析以“.”开头的行,得到程序如下:
g:
pushl %ebp
movl %esp ,%ebp
movl 8(%ebp) ,%eax
addl $11 ,%eax
popl %ebp
ret
f:
pushl %ebp
movl %esp ,%ebp
subl $4 ,%esp
movl 8(%ebp) ,%eax
movl %eax ,(%esp)
call g
leave
ret
main:
pushl %ebp
movl %esp ,%ebp
subl $4 ,%esp
movl $8 ,(%esp)
call f
addl $1 ,%eax
leave
ret
接下来逐行分析汇编代码,主要分析堆栈指针的变化情况:
1明确代码中用到的寄存器的默认功能eax:储存函数返回值。ebp:帧指针,储存堆栈的栈底位置esp:栈指针,储存堆栈的栈顶位置2假设main函数被调用之前,堆栈的栈底对应内存地址为100,栈顶对应内存地址为96,分别存放在ebp和esp内,并假设栈生长方向为内存的低字节方向。3从main函数的入口“main:”开始,- pushl %ebp
- movl %esp ,%ebp
- subl $4 ,%esp
- movl $8 ,(%esp)
- call f
- pushl %ebp
- movl %esp ,%ebp
- subl $4 ,%esp
- movl 8(%ebp) ,%eax
- movl %eax ,(%esp)
- call g
- pushl %ebp
- movl %esp ,%ebp
- movl 8(%ebp) ,%eax
- addl $11 ,%eax
- popl %ebp
- ret
- leave
- ret
- addl $1 ,%eax
- leave
- ret
by昆仑雪狐
原创作品转载请注明出处
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000