百科问答小站 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循环的汇编码不相同,因为两者可能恰好采取不同的优化方式。

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

以上,谢谢。




  

相关话题

  你见过最烂的代码长什么样子? 
  如何追到湾区码农小哥哥? 
  程序员的成长离不开哪些软技能? 
  如何优雅地叫一个程序员给我修电脑呢? 
  为什么中国出了这么多厉害的互联网公司,但没有自己设计过编程语言? 
  C 语言如何判断等差数列? 
  如何看待贴吧里的十五六岁就用引擎写游戏的开发者? 
  C语言仅凭自学能到什么高度? 
  刚开始学习Objective-C,面对Swift该怎么办? 
  为什么老板要教我们做互联网的程序员不要把工作和生活分开,这对于独立的程序员个体有什么好处? 

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





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