簡體   English   中英

為什么我不能在二進制文件中找到int值

[英]Why can't I find the int value in a binary

我在64位linux機器上編譯了以下程序:

#include <stdio.h>

main()
{
    int a = 12345;

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

    return;
}

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

(小端或大端應該在找到該值時沒有區別)

這是我在普通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而不是。

回答這類問題的最簡單方法是使用-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

您可以看到代碼中的數字12345和12346包含在movlcmpl指令中。

通過優化,代碼變得更加簡單。 編譯器可以看到if語句永遠不會計算為true。 它還可以看到變量a從未使用過。 這是使用硬優化( -O3 )編譯時main()樣子:

main:
        rep ret

注意:我在32位Ubuntu Xenial上編譯了這個,但在64位計算機上會發生完全相同的優化。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM