【问题标题】:g++ binary output analysisg++二进制输出分析
【发布时间】:2013-01-16 13:33:18
【问题描述】:

给定以下程序:

unsigned char g1[] = { 0x1a, 0x2a, 0x3a, 0x4a };
static unsigned char g2[] = { 0x1b, 0x2b, 0x3b, 0x4b };

int main()
{
  unsigned char l1[] = { 0x1c, 0x2c, 0x3c, 0x4c };
  static unsigned char l2[] = { 0x1d, 0x2d, 0x3d, 0x4d };
}

之后,简单地用“g++ test.cpp -o test”编译它并在二进制文件上运行hexdump -C,我意识到g1、g2和l2的序列可以在二进制文件中清楚地找到。只有 l1 (1c 2c 3c 4c) 的序列显然不存在于二进制文件的任何位置。

有人知道这是为什么吗?

【问题讨论】:

  • 为什么有人对这个问题投了反对票。我相信这是一个显而易见的问题。

标签: c++ binary g++ hexdump


【解决方案1】:

因为它是在该函数调用的堆栈上分配的。通常在这种情况下,会发生以下两种情况之一:

  1. 编译器将该序列存储在数据部分中,然后实质上将其memcpy 到堆栈缓冲区中。

  2. 编译器实质上对“移动”指令进行硬编码,以从指令集的最大立即值(通常是 4 字节整数)重新组装序列。

如果它没有被优化,就像提到的“放松”,那么#2 可能正在发生。查看反汇编程序(或预组装的 asm 代码)会更好地显示您。使用 -S 并查看 .s 文件。

【讨论】:

    【解决方案2】:

    我的猜测是因为它是非static 和自动的(非全局),所以知道没有人能够从外部引用它是微不足道的。由于没有被使用,所以可以丢弃。

    【讨论】:

      【解决方案3】:

      l1[]l2[] 在编译器优化期间被删除,因为它们都是 local and unused variables(不可能在其他任何地方使用这两个变量)。

      您可以使用-S 选项编译您的代码以生成汇编代码:并且在main 中没有l1[]l2[] 的定义,甚至在其他任何地方都没有:

      输入文件为x.c,用命令gcc -S x.c编译生成汇编文件x.s

      main:
          pushl   %ebp
          movl    %esp, %ebp
          subl    $16, %esp
          movb    $28, -4(%ebp)
          movb    $44, -3(%ebp)
          movb    $60, -2(%ebp)
          movb    $76, -1(%ebp)
          leave
          ret
          .size   main, .-main
          .data
          .type   l2.1250, @object
          .size   l2.1250, 4
      

      但是您可以找到g1[] and g2[] 的定义。

          .file   "x.c"
      .globl g1
          .data
          .type   g1, @object
          .size   g1, 4
      g1:
          .byte   26
          .byte   42
          .byte   58
          .byte   74
          .type   g2, @object
          .size   g2, 4
      g2:
          .byte   27
          .byte   43
          .byte   59
          .byte   75
          .text
      .globl main
          .type   main, @function  
      

      另外,如果你用标志-O3编译你的代码,如果你编译你会很有趣优化标志级别3那么只有g1[]的定义是展示。和全局静态变量(文件私有)也被删除。

      输入文件为x.c,用命令gcc -S -O3 x.c编译生成汇编文件x.s

      下面:

          .file   "x.c"
          .text
          .p2align 4,,15
      .globl main
          .type   main, @function
      main:
          pushl   %ebp
          movl    %esp, %ebp
          popl    %ebp
          ret
          .size   main, .-main
      .globl g1
          .data
          .type   g1, @object
          .size   g1, 4
      g1:
          .byte   26
          .byte   42
          .byte   58
          .byte   74
          .ident  "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
          .section    .note.GNU-stack,"",@progbits  
      

      g1[] 是仅存在的全局数据,g2[]-O3 中被删除。

      g2[] 使用已定义的static unsigned char g2[],因此只能在此文件中访问,不要再次使用未使用的。但是g1[] 是全局的,如果其他文件包含它,它可能对其他程序有用。并且编译器不允许优化掉全局对象。

      参考:How do I prevent my 'unused' global variables being compiled out?

      所以,这一切都归功于编译器优化!

      【讨论】:

      猜你喜欢
      • 2021-05-02
      • 1970-01-01
      • 2018-05-30
      • 1970-01-01
      • 1970-01-01
      • 2020-07-20
      • 1970-01-01
      • 2016-02-07
      • 2017-12-21
      相关资源
      最近更新 更多