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

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

以上,谢谢。




  

相关话题

  什么是 hash? 
  为什么我认为程序员似乎大多不善言辞? 
  程序员们在公司写的代码手头会私下里留一份吗? 
  GPU 与 CPU 比较,为什么说 GPU 更适合深度学习? 
  哪家 IT 公司不加班? 
  如何评价Jexus V5.8.0 发布被人砸场? 
  你在阅读源代码或设计文档时,看到哪些惊艳的技巧? 
  国内的程序员(软件工程师)这一职业,是吃青春饭的吗? 
  都说VB.NET是旧语言,那为什么很多高校里面还在教非计算机专业的学生学VB呢? 
  微软内部有哪些类似 Jeff Dean 的大神? 

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





© 2024-11-09 - tinynew.org. All Rights Reserved.
© 2024-11-09 - tinynew.org. 保留所有权利