[英]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包含在movl
和cmpl
指令中。
通過優化,代碼變得更加簡單。 編譯器可以看到if
語句永遠不會計算為true。 它還可以看到變量a
從未使用過。 這是使用硬優化( -O3
)編譯時main()
樣子:
main:
rep ret
( 注意:我在32位Ubuntu Xenial上編譯了這個,但在64位計算機上會發生完全相同的優化。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.