李俊锋 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”
一.实验内容
1.反汇编如下程序
- int g(int x)
- {
- return x + 4;
- }
- int f(int x)
- {
- return g(x);
- }
- int main(void)
- {
- return f(7) + 3;
- }
2.分析分析汇编代码的工作过程中堆栈的变化
二.实验原理
需要用到的知识:
三.实验过程
3.1使用如下命令,将c代码编译成汇编语言
- <span style="font-size:14px;">gcc –S –o main.s main.c -m32</span>
3.2 得到的汇编代码如下图所示:
- g:
- pushl %ebp
- movl %esp, %ebp
- movl 8(%ebp), %eax
- addl $4, %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 $7, (%esp)
- call f
- addl $3, %eax
- leave
- ret
3.3 分析每一条汇编代码以及函数栈的变化:
(1)pushl %ebp
本条指令的意思是将ebp寄存器指向的压栈,同时esp的值减4,栈如下图所示:(假设ebp和esp的值都是100)
(2)movl %esp, %ebp
将esp的值赋值给ebp,栈如下图所示:
(3)subl $4, %esp
本指令将esp的值减4,栈如下图所示:
(4)movl $7, (%esp)
本指令将数值7存到esp所指向的内存单元中,栈如下图所示:
(5)call f
本指令调用f函数,同时将返回地址压栈,返回地址就是main函数中下一条指令addl $3, %eax的地址,栈如下图所示:
(6)pushl %ebp
本指令再次将ebp压栈,栈如下所示:
(7)movl %esp, %ebp
本指令将esp的值赋值给ebp寄存器,栈如下图所示:
(8)subl $4, %esp
本指令是将esp的值减4,将esp向下移一位,栈如下图所示:
(9)movl 8(%ebp), %eax
将ebp+8单元中的值,也就是7赋值给eax寄存器,栈不变
(10)movl %eax, (%esp)
将eax中的值赋值给esp指向的单元中,栈如下图所示:
(11)call g
调用g函数,并将下一条指令leave的地址,也就是返回地址压栈,栈如下图所示:
(12)pushl %ebp
将ebp的值压栈,栈如下图所示:
(13)movl %esp, %ebp
将esp中的值赋值给ebp,栈如下图所示:
(14)movl 8(%ebp), %eax
将ebp+8单元中的值赋值7给eax寄存器,栈无变化
(15)addl $4, %eax
将eax中的值加4,结果存到eax中,也就是eax=7+4=11,程序中通常使用eax保存函数的返回值。
(16)popl %ebp
出栈,将值保存到ebp中,栈如下图所示:
(17)ret
函数返回,同时出栈,将下一条指令的值保存到eip中,栈如下图所示:
(18)leave
首先清空栈,将ebp中的值复制给esp,之后出栈,将值复制给ebp,栈如下图所示:
(19)ret
出栈,将值赋值给eip,栈如下图所示:
(20)addl $3, %eax
将eax中的值加3,结果保存在eax中,即:eax=11+3=14,栈不变
(21)leave
清空栈,将ebp中的值赋值给esp,同时出栈,将值保存到ebp中,栈如下图所示:
(22)ret
主函数返回,程序结束。
四.实验总结
计算机是如何工作的?
根据冯诺依曼结构,计算机可以分为控制器,存储器,运算器,输入设备,和输出设备。程序在运行是需要通过输入设备将程序的二进制机器码读入到内存之中,
内存中又分为代码段和数据段,代码段中的每一条指令指明了cpu下一步需要做的操作。计算机在运行时,先从内存中取出第一条指令,通过控制器的译码,
按指令的要求,从存储器中取出数据进行指定的运算和逻辑操作等加工,然后再按地址把结果送到内存中去。接下来,再取出第二条指令,
在控制器的指挥下完成规定操作。依此进行下去。直至遇到停止指令。最后将处理结果通过输出设备输出到显示器等设备上。
本次实验主要是让我们通过对at&t汇编的学习了解在程序运行时栈的变化。虽然内容并不是很多,但是受益匪浅,因为这门实验让我在信息安全课程之后,能更加深入的
了解at&t汇编的变成方法,对我学习linux系统大有裨益。