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

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得到汇编代码,实验截图如下:

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):

堆栈的初始状态:

                       

1. pushl     %ebp   

                               

2. movl      %esp, %ebp

                                  

ebp 指向标号为1的位置

3. subl      $4, %esp

                                  

4.  movl     $1,(%esp)     

                                       

5. call      f

    等同于这两条指令:push     %eip

                                     movl     f,%eip

    执行call指令时,eip实际指向的时call的下条指令,行号为23行的指令

                                                     

    此时,eip指向了f:,从第9行开始执行。

6. push     %ebp  

                                       

7.  movl    %esp,%ebp

                                                   

8. subl     $4,%esp

                                       

9. movl     8(%ebp),%eax       

   此时,堆栈无变化,变址寻址,ebp的值加8,就是标号为2的位置,将标号2的内容赋给寄存器eax,eax=1。

10. movl    %eax,(%esp)

                                        

11.   call    g  同上call  f 

                                               

12. pushl     %ebp    

                                      

13. movl      %esp,%ebp

                                        

14.  movl         8(%ebp),eax

         

        同上,堆栈无变化,eax=1

15. addl           $1,%eax

        堆栈无变化,eax加1,eax=2

16.popl            %ebp

                                    

ebp 又指向了原来标号为4的位置

17. ret 

     等同于指令:pop     %eip  

                                 

eip指向了代码第15行,执行指令leave

18. leave

      等同于这两条指令:movl     %ebp, %esp

                                       popl      %ebp

       堆栈变化为:movl      %ebp,%esp

                                      

                                  popl           %ebp

                                               

19. ret    

                                       

     此时,eip指向了代码第23行

20. addl       $1,%eax

             eax=2+1=3

21. leave

      同上,最后堆栈为:

                                   

最后回到main函数的最初的状态。

22. ret    返回到main函数之前的堆栈

3.总结:

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

                                           

猜你喜欢

转载自blog.csdn.net/wanghx_try/article/details/57160060