在32位机器上编译的汇编程序代码与使用" gcc -m32"编译的代码不同吗?

时间:2017-12-05 20:15:21

标签: gcc x86-64 cpu-architecture disassembly objdump

我现在正在学习汇编语言。我从中学习的书中的代码示例都是在x86 32位机器(我认为)上用gcc编译的。为了使我的输出与书中的输出相匹配,我使用" gcc -m32"编译了我的简单helloworld.c。

#include <stdio.h>

int main(){
    int i;
    for(i=0;i<10;i++){
      printf("Hello World!\n");
    }
    return 0;
}

我从运行&#34; objdump -D a32.out |得到的输出grep -A20 main.:"看起来像这样:

0000051d <main>:
51d:    8d 4c 24 04             lea    0x4(%esp),%ecx
521:    83 e4 f0                and    $0xfffffff0,%esp
524:    ff 71 fc                pushl  -0x4(%ecx)
527:    55                      push   %ebp
528:    89 e5                   mov    %esp,%ebp
52a:    53                      push   %ebx
52b:    51                      push   %ecx
52c:    83 ec 10                sub    $0x10,%esp
52f:    e8 ec fe ff ff          call   420 <__x86.get_pc_thunk.bx>
534:    81 c3 cc 1a 00 00       add    $0x1acc,%ebx
53a:    c7 45 f4 00 00 00 00    movl   $0x0,-0xc(%ebp)
541:    eb 16                   jmp    559 <main+0x3c>
543:    83 ec 0c                sub    $0xc,%esp
546:    8d 83 f0 e5 ff ff       lea    -0x1a10(%ebx),%eax
54c:    50                      push   %eax
54d:    e8 5e fe ff ff          call   3b0 <puts@plt>
552:    83 c4 10                add    $0x10,%esp
555:    83 45 f4 01             addl   $0x1,-0xc(%ebp)
559:    83 7d f4 09             cmpl   $0x9,-0xc(%ebp)
55d:    7e e4                   jle    543 <main+0x26>

但在书中它看起来像这样:enter image description here

它错过了我得到的输出中的前三行,除了接下来的两行外,它看起来并不像它。这是为什么 ?如何更改我的编译器/反汇编设置以使其看起来相似?

2 个答案:

答案 0 :(得分:2)

默认情况下,您的编译器配置为生成与位置无关的二进制文件,这会导致与本书的显着差异。 (这是最近的GCC开发)。

如果禁用此功能,您将更接近本书:

gcc -fno-pie -no-pie -m32 hello.c

正如其他人所说的,不能保证你会得到与本书中相同的代码,除非你得到完全相同的编译器内置完全相同的配置。

答案 1 :(得分:2)

gcc -m32一起运行的相同版本的gcc,无论在x86-64主机还是i386主机上运行,​​都应该是相同的。或者从ARM主机交叉编译!

区别在于gcc版本和默认设置。 (@Employed Russian指出,主要的一点是你的gcc默认启用了-fpie。相关:32-bit absolute addresses no longer allowed in x86-64 Linux?)默认情况下,PIE默认为32位有点不好代码也不仅仅是64,因为在32位模式下额外的开销更为显着(没有RIP相对寻址。)

除了-fno-pie之类的配置之外,不同版本的gcc会产生不同的代码。

无论如何,如果您真的想要与书中的内容相匹配,请尝试使用相同版本的gcc。 (希望他们提到这一点?如果没有,请查看发布的年份以获得粗略的暗示)。 您可以在http://gcc.godbolt.org/ 上尝试将每个gcc版本恢复到4.4。

这里有关于Godbolt的a link to your sample code,其中包含编译器asm输出和两个独立输出窗格中二进制文件的反汇编,两者都禁用了优化。

请注意,Matt Godbolt在没有default-pie配置的情况下配置gcc,但是您可以使用-fpie来获取asm,就像在桌面上一样。

请注意,对于未优化的代码,与您启用优化相比,它更依赖于gcc的内部。即-O0有点让你看看gcc&#34;如何思考&#34;你的程序,因为它甚至没有尝试优化。 (另外它会在每个语句之间溢出/重新加载以支持使用调试器更改变量;这是为什么它如此缓慢的原因之一:它故意将一个球和链子捆绑到你的所有这些额外的存储/重新加载使得阅读更加困难;我通常会查看-O2-O3输出。另请参阅How to remove "noise" from GCC/clang assembly output?