《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
依照学术诚信条款,我保证此回答为本人原创,所有回答中引用的外部材料已经做了出处标记。原创作品转载请注明出处 。
一、编写代码并生成汇编码。
1、代码如下:(来自课程作业)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/*file: 01.c*/ int g(int x) { return x+333; } int f(int x) { return g(x); } int main(void) { return f(111)+222; } |
实际截图:
2、编译生成汇编代码
1 |
gcc -S -o 01.s 01.c -m32 |
简化后的汇编代码:
1 |
vim 01.s |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
1 g: 2 pushl %ebp 3 movl %esp, %ebp 4 movl 8(%ebp), %eax 5 addl $333, %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 g 15 leave 16 ret 17 main: 18 pushl %ebp 19 movl %esp, %ebp 20 subl $4, %esp 21 movl $111, (%esp) 22 call f 23 addl $222, %eax 24 leave 25 ret |
为了真实性,晒一下截图:
二、汇编代码运行过程分析
####################################################
###############################################
- 第11行,%esp减去4个字节,空出来的空间用来存放未来的数据。
- 第12行,将距%ebp偏移值为8的数据保存至%eax寄存器中。数据正好是代码中的“111”。
- 第13行,将%eax寄存器中的值存放至栈顶位置。
- 第4行,将距%ebp偏移值为8的数据保存至%eax寄存器中,也就是将数值“111”保存至%eax中。
- 第5行,将立即数333与%eax寄存器中的数值相加,并保存在%eax寄存器中。
- 第6行,pop操作,将当前栈顶位置的ebp-2恢复至%ebp中,然后%esp的值自动加4。
################################################
- 第25行,ret,退出main(),程序运行结束,中间结果默认保存在了%eax中。
三、作业小结。
(对“计算机是如何工作的”理解)
从电路角度来说,计算机不过是一堆电子门电路的组合、叠加,因此其运行也就是分别代表0、1两个数值的高低电平所实现的。根据冯·诺依曼提出的“输入-存储-运算-输出”的结构,计算机的功能由运算器、存储器、控制器等核心部分组成。CPU内部有寄存器作为临时存储器,运算器,也有很重要的控制器。因此,计算机运算过程就是不间断地“取数据 - 运算 - 存数据”的循环。
从语言层面来讲,汇编语言是最接近机器语言的编程语言。实际上,每一条汇编指令都是一长串机器语言的集合。
每次开始执行一个程序,首先内存中需要一段空间用作程序的运行栈,然后利用栈“后进先出”的特性来记录程序的运行状态以及临时保存一些寄存器的值。CPU内部的运算器在控制器的控制下不断地与存取寄存器中的值,同时也通过总线与内存进行交互。