丁敬香原创作品转载请注明出处 《Linux操作系统分析》MOOC课程
近期有空学习《Linux操作系统分析》MOOC课程,通过了解CPU的主要部件和基本的汇编语句,使我对计算机的工作原理及栈(数据结构中)的应用有了更深刻的理解。
下面就以一段C语言程序编译所得到的汇编程序的工作过程来说明:
首先,在LINUX中建立一个C程序,如下图:
然后通过gcc命令进行编译后得到汇编程序,如下图:
这里,主要通过跟踪程序的执行过程,并观察ebp、esp、eax、eip及内存中栈里的数据变化来理解程序的执行及计算机的工作原理。其中,ebp和esp分别为保存栈底地址和栈顶地址的寄存器,eax可作为累加器使用,而eip为保存下一条要执行的指令的地址。
下表为每一语句的执行后各寄存器内容的变化和内存中数据的变化,假定起始栈底地址为1000,而eip指向main函数中的第一条语句(行号为18并假定其保存在内存地址为18的单元中)。
行号 | 语句 | eip | ebp | esp | eax | 内存中数据 |
|
| 18 | 1000 | 1000 |
|
|
18 | pushl%ebp |
| 1000 | 996 |
| addr996:ebp=1000 |
19 | movl%esp , %ebp |
| 996 | 996 |
|
|
20 | subl$4 , %esp |
| 996 | 992 |
|
|
21 | movl$7 , (%esp) |
|
|
|
| addr992:7 |
22 | callf | 9 |
| 988 |
| addr988:eip=23 |
9 | pushl%ebp |
|
| 984 |
| addr984:ebp=996 |
10 | movl%esp , %ebp |
| 984 |
|
|
|
11 | subl$4 , %esp |
|
| 980 |
|
|
12 | movl8(%ebp) , %eax |
|
|
| 7 | 将addr984+8=992中数据7,移至eax |
13 | movl%eax , (%esp) |
|
|
|
| addr980:7 |
14 | callg | 2 |
| 976 |
| addr976:eip=15 |
2 | pushl%ebp |
|
| 972 |
| addr972:ebp=984 |
3 | movl%esp , %ebp |
| 972 |
|
|
|
4 | movl8(%ebp) , %eax |
|
|
| 7 | 将addr972+8=980中数据7,移至eax |
5 | addl$9 , %eax |
|
|
| 16 |
|
6 | popl%ebp |
| 984 | 976 |
|
|
7 | ret | 15 |
| 980 |
|
|
15 | leave |
| 996 | 988 |
|
|
16 | ret | 23 |
| 992 |
|
|
23 | addl$3 , %eax |
|
|
| 19 |
|
24 | leave |
|
| 1000 |
|
|
25 | ret |
|
|
|
|
|