C++ 为什么要将此代码编译为C和C++;代码生成不同的程序集?
我编写了以下代码:C++ 为什么要将此代码编译为C和C++;代码生成不同的程序集?,c++,c,disassembly,C++,C,Disassembly,我编写了以下代码: int main() { int i; int arr[4]; for (i = 0; i < 4; i++) arr[i] = 0; return 0; } 我编辑了decompilec和decompilecpp,以便只包含主函数 现在,我运行diff decompilec decompilecpp,得到以下输出: 12,21c12,19 < 80483fe: 7e eb
int main()
{
int i;
int arr[4];
for (i = 0; i < 4; i++)
arr[i] = 0;
return 0;
}
我编辑了decompilec和decompilecpp,以便只包含主函数
现在,我运行diff decompilec decompilecpp
,得到以下输出:
12,21c12,19
< 80483fe: 7e eb jle 80483eb <main+0xf>
< 8048400: b8 00 00 00 00 mov eax,0x0
< 8048405: c9 leave
< 8048406: c3 ret
< 8048407: 66 90 xchg ax,ax
< 8048409: 66 90 xchg ax,ax
< 804840b: 66 90 xchg ax,ax
< 804840d: 66 90 xchg ax,ax
< 804840f: 90 nop
<
---
> 80483fe: 0f 9e c0 setle al
> 8048401: 84 c0 test al,al
> 8048403: 75 e6 jne 80483eb <main+0xf>
> 8048405: b8 00 00 00 00 mov eax,0x0
> 804840a: c9 leave
> 804840b: c3 ret
> 804840c: 66 90 xchg ax,ax
> 804840e: 66 90 xchg ax,ax
不同的语言使用不同的编译器前端,这可能会产生不同的指令流(在其他方面具有等效的语义效果)
如果您正在优化输出,那么优化器很可能(尽管不能保证)将两条指令流减少为相同的输出。。。但这并不能保证,我也不明白为什么你会期望有任何保证。有很多方法可以用汇编程序执行某些特定的操作。特别是当您进行任何优化时,这可能与目标CPU密切相关,汇编程序可能会有不明显的操作,这些操作基本上是为了使特定CPU工作得更快。即使你有相同的编译器和相同的优化标志,对于C和C++,实际使用的编译器仍然是不同的,因此它们可能会产生不同的代码。 C程序集应该很简单。C++版本更有趣。在那里发生的事情将在下一节中解释。基本上,他们将C代码的直接“小于等于跳转”转换为“根据小于等于设置为零或非零,然后基于零或非零跳转”
我不知道为什么C++编译器会产生这样的代码。它可能会随着更高的优化级别而更改,或者甚至是通过优化级别0生成,因为它有助于在大多数情况下对默认CPU进行分支预测以生成正确的预测。然后C编译器有不同的默认行为。正如我已经说过的,实际的编译器是不同的,所以我实际上有点惊讶于代码在其他方面是相同的那么,你期望C和C++产生相同的机器指令吗?若然,原因为何?机器指令必须是等效的,而不是完全相同的。所以问题是,它们是等价的吗?。但是,你知道足够的程序集来理解它们吗?我不敢相信一年半以前有一个几乎相同的问题:这似乎是一个完全合理的问题,包含足够的代码来重现问题和遇到的具体问题。我希望它能重新开放!另外,这个GCC错误报告(已修复)可能与此有关:伙计们,你们抽过烟吗?这是一个迭代次数恒定的零初始化循环(最好是在一个变量上,该变量在其他情况下不使用,之后立即超出范围)。打开
-O1
几乎肯定会删除整个代码,并将程序缩减为int main(){return 0;}
,而不管使用什么编译器或它可能有什么bug。甚至试图从一个空的main
函数中预言某些东西有什么意义呢?:-)
12,21c12,19
< 80483fe: 7e eb jle 80483eb <main+0xf>
< 8048400: b8 00 00 00 00 mov eax,0x0
< 8048405: c9 leave
< 8048406: c3 ret
< 8048407: 66 90 xchg ax,ax
< 8048409: 66 90 xchg ax,ax
< 804840b: 66 90 xchg ax,ax
< 804840d: 66 90 xchg ax,ax
< 804840f: 90 nop
<
---
> 80483fe: 0f 9e c0 setle al
> 8048401: 84 c0 test al,al
> 8048403: 75 e6 jne 80483eb <main+0xf>
> 8048405: b8 00 00 00 00 mov eax,0x0
> 804840a: c9 leave
> 804840b: c3 ret
> 804840c: 66 90 xchg ax,ax
> 804840e: 66 90 xchg ax,ax
080483dc <main>:
80483dc: 55 push ebp
80483dd: 89 e5 mov ebp,esp
80483df: 83 ec 20 sub esp,0x20
80483e2: c7 45 ec 00 00 00 00 mov DWORD PTR [ebp-0x14],0x0
80483e9: eb 0f jmp 80483fa <main+0x1e>
80483eb: 8b 45 ec mov eax,DWORD PTR [ebp-0x14]
80483ee: c7 44 85 f0 00 00 00 mov DWORD PTR [ebp+eax*4-0x10],0x0
80483f5: 00
80483f6: 83 45 ec 01 add DWORD PTR [ebp-0x14],0x1
80483fa: 83 7d ec 03 cmp DWORD PTR [ebp-0x14],0x3
80483fe: 7e eb jle 80483eb <main+0xf>
8048400: b8 00 00 00 00 mov eax,0x0
8048405: c9 leave
8048406: c3 ret
8048407: 66 90 xchg ax,ax
8048409: 66 90 xchg ax,ax
804840b: 66 90 xchg ax,ax
804840d: 66 90 xchg ax,ax
804840f: 90 nop
080483dc <main>:
80483dc: 55 push ebp
80483dd: 89 e5 mov ebp,esp
80483df: 83 ec 20 sub esp,0x20
80483e2: c7 45 ec 00 00 00 00 mov DWORD PTR [ebp-0x14],0x0
80483e9: eb 0f jmp 80483fa <main+0x1e>
80483eb: 8b 45 ec mov eax,DWORD PTR [ebp-0x14]
80483ee: c7 44 85 f0 00 00 00 mov DWORD PTR [ebp+eax*4-0x10],0x0
80483f5: 00
80483f6: 83 45 ec 01 add DWORD PTR [ebp-0x14],0x1
80483fa: 83 7d ec 03 cmp DWORD PTR [ebp-0x14],0x3
80483fe: 0f 9e c0 setle al
8048401: 84 c0 test al,al
8048403: 75 e6 jne 80483eb <main+0xf>
8048405: b8 00 00 00 00 mov eax,0x0
804840a: c9 leave
804840b: c3 ret
804840c: 66 90 xchg ax,ax
804840e: 66 90 xchg ax,ax
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.7/lto-wrapper
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.7.2-2ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1)