百科问答小站 logo
百科问答小站 font logo



C语言中, for 和 while 在汇编上有什么区别? 第1页

  

user avatar   zhu-wang-xiao-miao-o 网友的相关建议: 
      

看到有朋友提到《深入理解计算机系统结构》这本书了,我这边贴上一些学习资源供大家参考,和本题相关的内容在书中第三章,可以直接精准查阅。因为我只是按照前人的方法来自己去手动验证了一下生成汇编代码的结果,并没有谈及理论内容,所以我想提问者可能需要更系统和理论的支撑。

然后的话,我在回答最后把书中涉及到for和while的部分截图放上来了,不想下载的也可以直接看我的回答最后的附录。

1.英文版原书和配套资料(Computer Systems: A Programmer's Perspective(3rd))

2.中文版《深入理解计算机系统结构》(提取码wrzg)

关于本问题,我在Linux上做了一个测试程序:

首先写了下面的C代码文件test.c:

       #include <stdio.h>    int main() {          int i;          int j;          int sum = 0;            for (i = 0; i < 10; ++i) {                  sum += i;          }            j = 0;          while (j < 10) {                  sum += j;                  ++j;          }            return 0;  }       

接着编译一下:

gcc -o test test.c

然后使用objdump -d作为反汇编器得到汇编代码

objdump -d test> test.txt

打开test.txt看一下

       0000000000400474 <main>:    400474:   55                      push   %rbp    400475:   48 89 e5                mov    %rsp,%rbp    400478:   c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%rbp)    40047f:   c7 45 f4 00 00 00 00    movl   $0x0,-0xc(%rbp)    400486:   eb 0a                   jmp    400492 <main+0x1e>    400488:   8b 45 f4                mov    -0xc(%rbp),%eax    40048b:   01 45 fc                add    %eax,-0x4(%rbp)    40048e:   83 45 f4 01             addl   $0x1,-0xc(%rbp)    400492:   83 7d f4 09             cmpl   $0x9,-0xc(%rbp)    400496:   7e f0                   jle    400488 <main+0x14>    400498:   c7 45 f8 00 00 00 00    movl   $0x0,-0x8(%rbp)    40049f:   eb 0a                   jmp    4004ab <main+0x37>    4004a1:   8b 45 f8                mov    -0x8(%rbp),%eax    4004a4:   01 45 fc                add    %eax,-0x4(%rbp)    4004a7:   83 45 f8 01             addl   $0x1,-0x8(%rbp)    4004ab:   83 7d f8 09             cmpl   $0x9,-0x8(%rbp)    4004af:   7e f0                   jle    4004a1 <main+0x2d>    4004b1:   b8 00 00 00 00          mov    $0x0,%eax    4004b6:   c9                      leaveq     4004b7:   c3                      retq       4004b8:   90                      nop    4004b9:   90                      nop    4004ba:   90                      nop    4004bb:   90                      nop    4004bc:   90                      nop    4004bd:   90                      nop    4004be:   90                      nop    4004bf:   90                      nop      

可以看到

for循环的汇编代码如下:

       ...    40047f:   c7 45 f4 00 00 00 00    movl   $0x0,-0xc(%rbp)    400486:   eb 0a                   jmp    400492 <main+0x1e>    400488:   8b 45 f4                mov    -0xc(%rbp),%eax    40048b:   01 45 fc                add    %eax,-0x4(%rbp)    40048e:   83 45 f4 01             addl   $0x1,-0xc(%rbp)    400492:   83 7d f4 09             cmpl   $0x9,-0xc(%rbp)    400496:   7e f0                   jle    400488 <main+0x14>  ...      

while循环的汇编代码如下:

       ...    400498:   c7 45 f8 00 00 00 00    movl   $0x0,-0x8(%rbp)    40049f:   eb 0a                   jmp    4004ab <main+0x37>    4004a1:   8b 45 f8                mov    -0x8(%rbp),%eax    4004a4:   01 45 fc                add    %eax,-0x4(%rbp)    4004a7:   83 45 f8 01             addl   $0x1,-0x8(%rbp)    4004ab:   83 7d f8 09             cmpl   $0x9,-0x8(%rbp)    4004af:   7e f0                   jle    4004a1 <main+0x2d>  ...      

如你所见,这两个循环在程序集代码中遵循相同的结构,且操作数也都是相同的。

因此,对于在Linux上用GCC编译的C语言基本计数循环的默认优化来讲,while循环和for循环具有相同的性能。

当然,以上测试代码是比较简单的,在某些特殊情况下(例如动态条件等)可能某种循环结构的性能更好,或者因为编译器优化的方式不同而导致了不同的性能,这个还是需要具体问题来具体分析的。

按照书中的理论来说,GCC为for循环产生的优化可能是while循环优化的其中一种,这要取决于优化等级,我的理解是,这可能导致某些时候while和for循环的汇编码不相同,因为两者可能恰好采取不同的优化方式。

附《深入理解计算机系统》相关摘录:

以上,谢谢。




  

相关话题

  为什么大学程序设计老师不去外面公司当程序员? 
  操作系统里面经常说的一个功能用「软件实现」还是用「硬件实现」,其本质区别是什么? 
  学习编程的过程中是否真的需要敲代码?复制粘贴不行吗? 
  TDD(测试驱动开发)是否已死? 
  如何快速地在每个函数入口处加入相同的语句? 
  c++程序员怎么搭建一个完整的个人网站? 
  使用yield可以做哪些很酷的事情? 
  作为一个程序员,怎么看待今年互联网寒冬、裁员?要如何应对? 
  用c#开发桌面应用,如何做出漂亮的界面? 
  MYSQL 什么时候返回空,什么时候返回NULL,为什么这两条语句返回结果不一样? 

前一个讨论
有哪些值得你推荐的百科全书?
下一个讨论
如何评价南开大学程明明老师的 DOCX 倡议(开放共享科研记录行动倡议)?





© 2024-12-26 - tinynew.org. All Rights Reserved.
© 2024-12-26 - tinynew.org. 保留所有权利