为什么我不能在二进制文件中找到int值

时间:2017-02-13 10:57:34

标签: c linux elf hexdump

我在64位Linux机器上编译了以下程序:

#include <stdio.h>

main()
{
    int a = 12345;

    if (a == 12346)
        printf ("YES\n");

    return;
}

如果我使用hexdump输出二进制文件,我可以找到12346(十六进制为303a),但不能找到12345值(0x3039)。那是为什么?

(小端或大端应该在找到该值时没有区别)

2 个答案:

答案 0 :(得分:6)

这是我在普通hexdump输出中的值的位置;看看粗体区域。

0000500 39fc 0030 8100 fc7d 303a 0000 0a75 a4bf

如果您希望将3039视为一个群组,则可以解释这种混淆。实际的字节是:

fc 39 30 00 00 81 7d fc 3a 30 00 00 75 0a bf a4

如果您不希望hexdump执行其“有用”的默认输出,并将输入重新解释为一系列小端双字节字,您可能需要花费一个小时来确定如何使用其格式字符串或只是选择xxd。

答案 1 :(得分:4)

回答这类问题的最简单方法是使用-S命令行选项对其进行编译,该选项将您的C程序输出为汇编代码。

这是您的main()函数在没有任何优化的情况下编译的(即使用-O0命令行开关)。我删除了一些冗余的标记语句并添加了一些注释:

main:
        leal    4(%esp), %ecx        # Create local storage on stack
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ecx
        subl    $20, %esp
        movl    $12345, -12(%ebp)   # Initialize `a` to 12345
        cmpl    $12346, -12(%ebp)   # Compare with 12346
        jne     .L4
        subl    $12, %esp           # If equal, ...
        pushl   $.LC0
        call    puts                # print "YES"
        addl    $16, %esp
.L4:
        nop
        nop
        movl    -4(%ebp), %ecx      # Tidy up and exit
        leave
        leal    -4(%ecx), %esp
        ret

您可以在movlcmpl说明中看到代码中包含数字12345和12346。

通过优化,代码变得更加简单。编译器可以看到if语句永远不会计算为true。它还可以看到变量a从未使用过。这是main()在使用硬优化(-O3)编译时的样子:

main:
        rep ret

注意:我是在32位Ubuntu Xenial上编译的,但在64位计算机上会发生完全相同的优化。)