(作业1)将一个简单的C程序编译成汇编代码,讨论计算机是如何工作的进行
作业题目:
根据本周所学知识分析汇编代码的工作过程,撰写一篇署名博客,并在博客文章中注明“真实姓名(与最后申请证书的姓名务必一致) + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”,博客内容的具体要求如下:
- 题目自拟,内容围绕计算机是如何工作的进行;
- 博客中需要使用实验截图
- 博客内容中需要仔细分析汇编代码的工作过程中堆栈的变化
- 总结部分需要阐明自己对“计算机是如何工作的”理解。
作答区:
1. C语言代码如下:
int g(int x) { return x + 31; } int f(int x) { return g(x); } int main(void) { return f(17) + 12; }
2. 按下键盘的ESC按钮,并输入:wq,保存并退出。
3. 输入如下代码进行编译:
gcc –S –o main.s main.c -m32
4. 输入vim main.s,查看汇编之后的代码,代码的一部分截图如下:
5. 将所有带.的代码删除,留下纯正的汇编代码:
1 g: 2 pushl %ebp ;12. 把ebp(4)放入位置6,
esp指向下一个标号(7) 3 movl %esp, %ebp ;13.
ebp也指向位置7 4 movl 8(%ebp), %eax; 14.
ebp+8指向标号5(位置4), eax = 17 5 addl $31, %eax ; 15. eax = eax + 3 = 17 + 31 = 48 6 popl %ebp ; 16. ebp = 4, esp指向上一个标号(6) 7 ret ; 17. eip = 15, esp指向上一个编号(5) 8 f: 9 pushl %ebp ; 6. ebp(1)放入位置3, esp指向下一个标号(4) 10 movl %esp, %ebp ; 7. ebp也指向标号4 11 subl $4, %esp ; 8. esp指向下一个标号(5) 12 movl 8(%ebp), %eax ; 9. ebp+8指向标号2(位置1), eax = 17 13 movl %eax, (%esp) ; 10. 把17放入位置5 14 call g ; 11. 把eip(15)放入位置5, esp指向下一个标号(6) 15 leave ; 18. esp = ebp = 4; ebp = 1, esp = 3(esp = esp - 1) 16 ret ; 19. esp指向上一个位置(2), 同时eip = 23 17 main: 18 pushl %ebp ; 1. 把ebp的值放入堆栈,位于位置0,同时esp的值被修改(标号1) 19 movl %esp, %ebp ; 2. ebp也指向esp的位置(标号1) 20 subl $4, %esp ; 3. esp减4,指向下一个标号(2) 21 movl $17, (%esp) ; 4. 把17放入位置1 22 call f ; 5. 把eip(23)放入位置2, 同时esp指向下一个标号(3) 23 addl $12, %eax ; 20. eax = 48 + 12 = 60 24 leave ; 21. esp = ebp = 1, ebp = 0, esp = 0(esp = esp - 1) 25 ret ; 22. 回到main函数之前的堆栈
6. 代码分析及堆栈的变化参见注释,从编号1. 一直到编号22. 。参考下图所示的栈结构阅读注释,会更加明确:
7. 计算机是如何工作的?
自己的理解是这样的:eip存储下一条指令的地址,ebp存储栈底指针,esp存储栈顶指针。通过栈来保存现场、传递数据。
作者:李春霖
原创作品转载请注明出处
《Linux内核分析》MOOC课程地址:http://mooc.study.163.com/course/USTC-1000029000