通过汇编一个简单的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.总结:

 

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

                                           

 

 

1、选择合适的算法和数据结构 2、使用尽量小的数据类型 3、减少运算的强度 (1)查表 (2)求余运算 (3)平方运算 (4)用移位实现乘除法运算 (5)避免不必要的整数除法 (6)使用增量和减量操作符 (7)使用复合赋值表达式 (8)提取公共的子表达式 4、结构体成员的布局 (1)按数据类型的长度排序 (2)把结构体填充成最长类型长度的整倍数 (3)按数据类型的长度排序本地变量 (4)把频繁使用的指针型参数拷贝到本地变量 5、循环优化 (1)充分分解小的循环 (2)提取公共部分 (3)延时函数 (4)while循环和do…while循环 (5)循环展开 (6)循环嵌套 (7)Switch语句中根据发生频率来进行case排序 (8)将大的switch语句转为嵌套switch语句 (9)循环转置 (10)公用代码块 (11)提升循环的性能 (12)选择好的无限循环 6、提高CPU的并行性 (1)使用并行代码 (2)避免没有必要的读写依赖 7、循环不变计算 8、函数 (1)Inline函数 (2)不定义不使用的返回值 (3)减少函数调用参数 (4)所有函数都应该有原型定义 (5)尽可能使用常量(const) (6)把本地函数声明为静态的(static) 9、采用递归 10、变量 (1)register变量 (2)同时声明多个变量优于单独声明变量 (3)短变量名优于长变量名,应尽量使变量名短一点 (4)在循环开始前声明变量 11、使用嵌套的if结构
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值