实验内容:
反汇编一个简单的C程序
实验过程:
1.创建main.c文件
2.编译并执行main.c文件
3.编译成汇编代码main.s




汇编指令中频繁使用了三个寄存器ebp, esp和eax。
其中ebp是基址指针寄存器;
esp是栈指针寄存器,通常指向栈顶;
eax可以暂存数据,同时也作为函数返回值的默认存储位置。
从main.s文件中可以清楚的看到三个函数的汇编代码
实验分析:
g:
pushl %ebp //保存调用函数的基址(ebp中)到栈中,压栈操作此时esp自动下移一个地址空间(4个字节)
movl %esp, %ebp //将esp的内容放到ebp中,设置ebp为当前被调用函数的基址指针,即当前栈顶
movl 8(%ebp), %eax //将ebp上移2个地址空间的内容放到eax中,就是数字5
addl $1, %eax //将1与eax中的数相加,也就是6放到eax中
popl %ebp //恢复ebp为调用函数基址
ret //就是f函数中的leave
f:
pushl %ebp //保存调用函数的基址(ebp中)到栈中,压栈操作此时esp自动下移一个地址空间(4个字节)
movl %esp, %ebp //将esp的内容放到ebp中,设置ebp为当前被调用函数的基址指针,即当前栈顶
subl $4, %esp //esp下移一个地址空间(4个字节),为当前函数分配1个栈空间(4个字节)用于存储局部变量
movl 8(%ebp), %eax //ebp中的地址上移2个(8个字节)地址空间的内容放到eax中,也就是将数字5放到eax中
movl %eax, (%esp) //将eax中的内容放到esp当前指向的位置
call g //将此时eip中的值压栈,然后将g函数的地址放到eip中,这样程序转而执行g函数。
leave //执行完g函数后返回此处,将ebp中的那内容放到esp,将回复ebp为调用函数基址
ret //是main函数中的addl $1, %eax
main:
pushl %ebp //保存调用函数的基址(ebp中)到栈中,压栈操作此时esp自动下移一个地址空间(4个字节)
movl %esp, %ebp //将esp的内容放到ebp中,设置ebp为当前被调用函数的基址指针,即当前栈顶
subl $4, %esp //esp下移一个地址空间(4个字节),为当前函数分配1个栈空间(4个字节)用于存储局部变量
movl $5, (%esp) //将5放到esp当前指向的位置
call f //将此时eip中的值压栈,然后将f函数的地址放到eip中,这样程序转而执行f函数。
addl $1, %eax //将1与eax中的内容相加,也就是1+6=7,将7放到eax中
leave //将ebp中的那内容放到esp,将回复ebp为调用函数基址
ret //返回main函数之前的堆栈
可以观察到频繁出现的代码
pushl %ebp
movl %esp, %ebp
作用为保存现场,与恢复现场相对应。
实验中遇到的问题和收获:
主要是对各个寄存器的名字及其作用的掌握程度不够熟练,通过查阅庖丁解牛Linux 分析及网上相关知识,
更加熟练的了解了相关寄存器作用知识,学习了函数调用堆相关知识