2019-2020-1 20209310《Linux内核原理与分析》第二周作业
反汇编简单C程序
- 创建工作目录,然后编写main.c文件
- 通过以下命令编译汇编代
$ gcc –S –o main.s main.c -m32
3.删除main.c文件中"."开头的代码,得到纯汇编代码
`g:
12 pushl %ebp
13 movl %esp, %ebp
14 movl 8(%ebp), %eax
addl $3, %eax
popl %ebp
ret
f:
pushl %ebp
movl %esp, %ebp
sub $4,%esp
movl $8(%ebp),%eax
movl %eax,(%esp)
11call g
leave
ret
main:
pushl %ebp
movl %esp, %ebp
sub $4,%esp
movl $8,(%esp)
call f
addl $1, %eax
leave
ret`
4.对代码进行分析
- push指令:压栈
- mov指令: 赋值指令
- pop指令:出栈
- b、w、l、p:分别对应8位、16位、32位、64位
程序从main函数开始运行
第一条指令为pushl %ebp
,即把EBP寄存器的值压栈,ESP下移1个单元。
第二条:把ESP寄存器的值赋值给EBP寄存器,实质上是建立main函数自己的函数调用堆栈空间。
第三条:ESP寄存器的值减4,即ESP下移。
第四条:把立即数8放到ESP指向的位置。
第五条:调用f函数,开始执行f函数的指令。
第六条:把EBP寄存器的值压栈。
第七条:把ESP寄存器的值赋值给EBP寄存器,实质上是建立f函数自己的函数调用堆栈空间。
第八条:ESP寄存器的值减4,即ESP下移1个单元。
第九条:通过EBP寄存器变址寻址,EBP寄存器的值加8,即向上移动2个单元,立即数8被放到了EAX寄存器中。
第十条:把EAX寄存器中的值8放到ESP寄存器。
第十一条:调用g函数,开始执行g函数的指令。
第十二条和第十三条:同样是建立g函数的函数调用空间。
第十四条:通过EBP寄存器变址寻址,EBP寄存器的值加8,即向上移动2个单元,立即数8被放到了EAX寄存器中。
第十五条:把EAX寄存器里的值加3,也就是11。
第十六条和第十七条:拆除g函数调用堆栈,并返回到调用函数g的位置。
第十八条:返回到f函数的断点后,执行指令leave,撤销函数堆栈。
第十九条:返回main函数断点。
第二十条:把EAX寄存器中的值加1,得到12。
第二十一和二十二条:撤销main函数堆栈,返回初始状态。