通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作

时间:2022-09-10 00:55:54

1.简单的c程序如下:          

  1. int g(int x)
  2. {
  3.   return x + 1;
  4. }
  5.  
  6. int f(int x)
  7. {
  8.   return g(x);
  9. }
  10.  
  11. int main(void)
  12. {
  13.   return f(1) + 1;
  14. }
通过命令 gcc -S -o main.s main.c -m32得到汇编代码,实验截图如下:
通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作

2.汇编代码的工作过程中堆栈的变化如下:
1)几个寄存器的说明:
eip:自动执行下一条指令。
ebp:指向堆栈栈底。
esp:指向堆栈栈顶。
eax:函数返回默认使用eax寄存器返回上一级函数。
2)关于push和pop指令的说明(32位):
push:esp的值减4。
pop:esp的值加4。
3)下面仔细说明各指令执行时堆栈的变化(从main函数开始,为了方便模拟堆栈的变化,采用标号的形式,每一个标号代表4个 字节,执行push操作esp指向的标号就加1,pop操作esp指向的标号就减1):
堆栈的初始状态:
                       通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
1. pushl     %ebp   
                               通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
2. movl      %esp, %ebp
                                  通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
ebp 指向标号为1的位置

3. subl      $4, %esp
                                  通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
4.  movl     $1,(%esp)     
                                       通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
5. call      f
    等同于这两条指令:push     %eip
                                     movl     f,%eip
    执行call指令时,eip实际指向的时call的下条指令,行号为23行的指令
                                                     通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
    此时,eip指向了f:,从第9行开始执行。
6. push     %ebp  
                                       通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
7.  movl    %esp,%ebp
                                                   通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
8. subl     $4,%esp
                                       通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
9. movl     8(%ebp),%eax       
   此时,堆栈无变化,变址寻址,ebp的值加8,就是标号为2的位置,将标号2的内容赋给寄存器eax,eax=1。

10. movl    %eax,(%esp)
                                        通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
11.   call    g  同上call  f 
                                               通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
12. pushl     %ebp    
                                      通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
13. movl      %esp,%ebp
                                        通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
14.  movl         8(%ebp),eax
         
        同上,堆栈无变化,eax=1

15. addl           $1,%eax
        堆栈无变化,eax加1,eax=2
16.popl            %ebp
                                    通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
ebp 又指向了原来标号为4的位置

17. ret 
     等同于指令:pop     %eip  
                                 通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
eip指向了代码第15行,执行指令leave

18. leave
      等同于这两条指令:movl     %ebp, %esp
                                       popl      %ebp
       堆栈变化为:movl      %ebp,%esp
                                      通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
                                  popl           %ebp
                                               通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
19. ret    
                                       通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
     此时,eip指向了代码第23行
20. addl       $1,%eax
             eax=2+1=3
21. leave
      同上,最后堆栈为:
                                   通过汇编一个简单的C程序,分析汇编代码,理解计算机如何工作
最后回到main函数的最初的状态。
22. ret    返回到main函数之前的堆栈
 
3.总结:

        计算机的工作过程就是处理一个有一个程序的过程,计算机在执行程序时,预先要把指挥计算机如何进行操作的指令序列(称为程序)和原始数据通过输入设备输送到计算机内存寄存器中。每一条指令中明确规定了计算机从哪个地址取数,进行什么操作,然后送到什么地址去等步骤。计算机在运行时,先从内存中取出第一条指令,通过控制器的译码,按指令的要求,从存储器中取出数据进行指定的运算和逻辑操作等加工,然后再按地址把结果送到内存中去。接下来,再取出第二条指令,在控制器的指挥下完成规定操作。依此进行下去。直至遇到停止指
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000