【问题标题】:Changing compiler optimization levels doesn't change the compiled binary更改编译器优化级别不会更改已编译的二进制文件
【发布时间】:2020-05-16 06:55:18
【问题描述】:

我一直在使用arm-linux-gnueabi-gcc 工具链将二进制文件交叉编译为arm。奇怪的是,尽管我更改了优化级别,但编译的二进制文件没有任何差异。甚至我也在关注来自“arm”的this 文档,并从中获取了相同的来源。

#include <stdio.h>
int main(){

   int x =10, y =20;
   int z;
   z =x+y;
   return 0;

}

我什至浏览了man 页面,我认为我正确使用了优化标志。这是我用来编译的确切代码。

arm-linux-gnueabi-gcc -O1 -o test test.c 

但是,无论我如何更改上述 arm 文档中所示的优化级别,“测试”目标文件的生成都不会改变(编译后的二进制文件的大小是相同的)。可能是什么原因?我在这里做错了吗?提前致谢。

【问题讨论】:

  • The size of the compiled binary is the same - 你是如何测量尺寸的?你为什么希望它改变?
  • 我使用ls -al 来获取大小。根据我正在阅读的arm 文档,随着优化级别的提高,大小确实会发生变化。但在我的情况下,即使在最高优化级别也没有改变,无论在 arm 文档中使用相同的源代码
  • 您是否使用 objdump 检查了您的两个二进制文件?也许text 部分包含很多填充?
  • According to the arm documentation - 什么文档?您确定他们提到的是 文件 的大小,而不是 .bss 部分的大小或其他任何内容吗?优化选项可能会增加可执行文件的大小,因为编译器可能会牺牲大小来换取速度。你不能做出“它总是会更小”这样的假设。编译器可能会插入填充 nop 指令以将您的指令与某个边界对齐。

标签: gcc arm cross-compiling compiler-optimization


【解决方案1】:
arm-linux-gnueabi-gcc -O0 -c so.c -o so.o
arm-linux-gnueabi-objdump -D so.o

so.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <main>:
   0:   e52db004    push    {fp}        ; (str fp, [sp, #-4]!)
   4:   e28db000    add fp, sp, #0
   8:   e24dd014    sub sp, sp, #20
   c:   e3a0300a    mov r3, #10
  10:   e50b3010    str r3, [fp, #-16]
  14:   e3a03014    mov r3, #20
  18:   e50b300c    str r3, [fp, #-12]
  1c:   e51b2010    ldr r2, [fp, #-16]
  20:   e51b300c    ldr r3, [fp, #-12]
  24:   e0823003    add r3, r2, r3
  28:   e50b3008    str r3, [fp, #-8]
  2c:   e3a03000    mov r3, #0
  30:   e1a00003    mov r0, r3
  34:   e24bd000    sub sp, fp, #0
  38:   e49db004    pop {fp}        ; (ldr fp, [sp], #4)
  3c:   e12fff1e    bx  lr

arm-linux-gnueabi-gcc -O1 -c so.c -o so.o
arm-linux-gnueabi-objdump -D so.o

so.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <main>:
   0:   e3a00000    mov r0, #0
   4:   e12fff1e    bx  lr

其余优化级别应该产生与 -O1 相同的结果,因为这是死代码,并且通过简单的优化将其全部删除。

这里的关键是当你说“二进制”时,我假设你的意思是由

创建的输出文件
arm-linux-gnueabi-gcc -O1 -o test test.c

那个“测试”文件包含很多东西,对于像这样的简单程序,几乎没有一个是实际代码。

如果您检查目标文件的大小(上面的 so.o)而不是链接的二进制文件,您应该会看到差异或使用 arm-whatever-objcopy -O 二进制文件,您“可能”会看到差异,它可能那里也很吵。

-O0 对象为 880 字节,-O1 为 824 字节,但正如您在 由于优化,反汇编有很好的尺寸差异。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 2020-04-29
    • 2012-12-13
    • 1970-01-01
    相关资源
    最近更新 更多