linux内核分析作业:以一简单C程序为例,分析汇编代码理解计算机如何工作

一、实验

使用gcc –S –o main.s main.c -m32

命令编译成汇编代码,如下代码中的数字请自行修改以防与他人雷同

 1 int g(int x)
 2 {
 3   return x + 3;
 4 }
 5 int f(int x)
 6 {
 7   return g(x);
 8 }
 9 int main(void)
10 {
11   return f(8) + 1;
12  }

修改过后源代码:

经过编译过的原始汇编代码:

简单地汇编代码:

 1 g:
 2     pushl    %ebp
 3     movl    %esp, %ebp
 4     movl    8(%ebp), %eax
 5     addl    $4, %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    $2, (%esp)
22     call    f
23     addl    $3, %eax
24     leave
25     ret

堆栈变化图:

在汇编代码中分析堆栈变化:

 1 g:
 2     pushl    %ebp      ;ebp4入栈 ebp指向4 esp指向7
 3     movl    %esp, %ebp   ;ebp = esp =7
 4     movl    8(%ebp) ,%eax ;eax = 2
 5     addl    $4, %eax ;eax + 4 = 6
6 popl %ebp ;ebp出栈 ebp指向esp1 esp减4 7 ret ;ret = pop eip eip14出栈 esp指向5 8 f: 9 pushl %ebp ;ebp1入栈 ebp指向1 esp指向4 10 movl %esp, %ebp ;ebp = esp =4 11 subl $4, %esp ;esp -4 指向5 12 movl 8(%ebp), %eax ;ebp+8=eax 指向2 eax = 2 13 movl %eax, (%esp) ;把eax放入esp所指的位置 14 call g ;调用g函数 eip15入栈 15 leave ;leave = movl %ebp %esp popl %ebp esp = ebp = 4 ebp1出栈 ebp指向1 esp-4指向3 16 ret ;eip23出栈 esp-4指向2 17 main: 18 pushl %ebp ;ebp0入栈 ebp指向0 esp指向1 19 movl %esp, %ebp ;ebp = esp =1 20 subl $4, %esp ; esp-4 esp指向2 21 movl $2, (%esp) ;2入栈 22 call f ;调用f函数 push eip movl eip eip23入栈 23 addl $3, %eax ;eax+3 24 leave ; esp = ebp = 1 esp0出栈 ebp = 0 ebp-4 = 0 25 ret

 

 

总结:

  通过这个小实验,可以清楚地认识冯.诺依曼体系,也就是计算机工作的过程,通过各种的寄存器存放数据或指令,系统在通过指令一步一步向下执行。从这个堆栈的分析可以看出系统先将main函数压入栈中,调用f函数时将f函数压入栈中,调用g函数同样如此;在g函数使用完毕后,释放g函数所占用的堆栈,继续执行未执行完的函数命令,直到程序运行完毕或者出错。也就是说计算机工作就像是流水线一步一步取指译码执行。

              郭皓原创作品转载请注明出处   《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 

posted @ 2016-02-27 19:45  20135327郭皓  阅读(286)  评论(0编辑  收藏  举报