main.c如下:
int g(int x) { return x + 3; } int f(int x) { return g(x); } int main(void) { return f(8) + 1; }
然后反汇编:
gcc –S –o main.s main.c -m32
生成main.s汇编文件,打开去掉前面有点“.”的行(这些行在汇编中没什么用起辅助作用)如下:
1 h: 2 pushl %ebp 3 movl %esp, %ebp 4 movl 8(%ebp), %eax 5 addl $2, %eax 6 popl %ebp 7 ret 8 f: 9 pushl %ebp 10 movl %esp, %ebp 11 subl $4, %esp 12 movl 8(%ebp), %eax 13 movl %eax, (%esp) 14 call h 15 leave 16 ret 17 main: 18 pushl %ebp 19 movl %esp, %ebp 20 subl $4, %esp 21 movl $4, (%esp) 22 call f 23 addl $1, %eax 24 leave 25 ret%eax通用寄存器默认存储函数的返回值,%ebp:指向栈基址,%esp指向栈顶,
pushl 是向入栈,栈的地址是向低地址增加的。
popl 是出栈
leave(enter leve 是一组)等价于:movl %ebp %esp; popl %ebp就是把暂时的栈收回,把栈顶存的ebp返回给ebp.
enter 等价于:pushl %ebp; movl %esp %ebp
ret是return,等价于popl %eip; subl $4 %esp 即把原来存储的地址返回,栈指针++
注意每次push,pop,%esp都会改变的++或者--
然后自己画个堆栈分析就是了。