g ++二进制输出分析

时间:2013-01-16 13:33:18

标签: c++ binary g++ hexdump

鉴于以下计划:

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)的序列显然不存在于二进制文件中的任何地方。

有人知道为什么会这样吗?

3 个答案:

答案 0 :(得分:4)

因为它是在该函数调用的堆栈上分配的。通常在这种情况下,两件事中的一件会很高兴:

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

  2. 编译器基本上硬编码“移动”指令,以从指令集的最大立即值(通常为4-bye int)重新组装序列。

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

答案 1 :(得分:3)

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

答案 2 :(得分:0)

在编译器优化期间删除了

l1[]l2[],因为它们都是local and unused variables(两个变量都不会在任何其他位置使用)。

您可以使用-S选项编译代码以生成汇编代码:并且主要内容中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 编译代码,那么知道您是否编译会很有趣,然后只定义{{ 1}}存在。和全局静态变量(文件专用)也被删除。

输入文件为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[]是全局的,如果其他文件包含它,则其他程序可能会有用。并且不允许编译器优化全局对象。

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

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