2017-10-18 118 views
0

我想知道有什么区别:为什么gcc为使用不同形式的整数文字的程序产生不同的编译二进制文件?

int a = 0b00000100; 
int a = 0x04; 
int a = 4; 

当用gcc编译。

我似乎得到一个不同的二进制文件,当编译似乎是相同的数字,只是在不同的符号。但是,当我运行objdump时,似乎没有任何区别。有人能告诉我发生了什么事吗?

这是我的输出:

[email protected]:[~]: cat testbin.c && echo && cat testbin2.c 
#include "stdio.h" 
int main() { 
    int a = 0b00000100; 
    int b = 0x05; 
    int c = 6; 
    printf("%d - %d - %d\n", a, b, c); 
    return (0); 
} 

#include "stdio.h" 
int main() { 
    int a = 4; 
    int b = 5; 
    int c = 6; 
    printf("%d - %d - %d\n", a, b, c); 
    return (0); 
} 
[email protected]:[~]: gcc testbin.c -o testbin 
[email protected]:[~]: gcc testbin2.c -o testbin2 
[email protected]:[~]: md5sum testbin testbin2 
fd6aaa31bdf685ea9444e1edc209565e testbin 
3a3fc241bfc2917ee29999b5befecd2a testbin2 
[email protected]:[~]: objdump -d testbin > testbin.obj && objdump -d testbin2 > testbin2.obj 
[email protected]:[~]: diff testbin.obj testbin2.obj 
2c2 
< testbin:  file format elf64-x86-64 
--- 
> testbin2:  file format elf64-x86-64 
[email protected]:[~]: gcc -v 
Using built-in specs. 
COLLECT_GCC=gcc 
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/6/lto-wrapper 
Target: x86_64-linux-gnu 
Configured with: ../src/configure -v --with-pkgversion='Debian 6.3.0-18' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-6 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu 
Thread model: posix 
gcc version 6.3.0 20170516 (Debian 6.3.0-18) 
[email protected]:[~]: 

注意,可执行文件是不同的,他们有不同的哈希值,但objdump -d不显示任何不同。

+0

它们不是同一个文件。你为什么期望校验和是一样的? https://en.wikipedia.org/wiki/Md5sum –

+0

注意'0b00000100;'不是标准C. – chux

+0

@KenWhite我不记得它编译过的原始文件名。 –

回答

1

我认为这个问题与整数格式无关并且与文件名有关。

我整理了以下程序两次,第一次使用的文件名FIRST_PROG.c和可执行文件名COMPILED_1和第二次使用使用gcc未设置任何其他标志名SECOND_PROC.c和可执行名称COMPILED_2

int main() { 
    return 0; 
} 

如果hd生成的可执行文件的内容,在一定的偏移量处看到:

00001720 66 72 61 6d 65 5f 64 75 6d 6d 79 5f 69 6e 69 74 |frame_dummy_init| 
00001730 5f 61 72 72 61 79 5f 65 6e 74 72 79 00 46 49 52 |_array_entry.FIR| 
00001740 53 54 5f 50 52 4f 47 2e 63 00 5f 5f 46 52 41 4d |ST_PROG.c.__FRAM| 

通知源文件的名称FIRST_PROG.c已嵌入生成的可执行文件中。看着在第二个文件的同一位置显示了这个:

00001720 66 72 61 6d 65 5f 64 75 6d 6d 79 5f 69 6e 69 74 |frame_dummy_init| 
00001730 5f 61 72 72 61 79 5f 65 6e 74 72 79 00 53 45 43 |_array_entry.SEC| 
00001740 4f 4e 44 5f 50 52 4f 47 2e 63 00 5f 5f 46 52 41 |OND_PROG.c.__FRA| 

你可以看到SECOND_PROG.c嵌入到二进制为好。

将两个可执行文件与objdump -s一起转储并不会在任何地方显示,这与您从程序中清除的diff相符。但是,使用readelf -a列出系统产生可执行文件的内容确实显示此:

Symbol table '.symtab' contains 66 entries: 
    Num: Value   Size Type Bind Vis  Ndx Name 
    0: 0000000000000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 0000000000400238  0 SECTION LOCAL DEFAULT 1 
    2: 0000000000400254  0 SECTION LOCAL DEFAULT 2 
    3: 0000000000400274  0 SECTION LOCAL DEFAULT 3 
    4: 0000000000400298  0 SECTION LOCAL DEFAULT 4 
    5: 00000000004002b8  0 SECTION LOCAL DEFAULT 5 
    6: 0000000000400300  0 SECTION LOCAL DEFAULT 6 
    7: 0000000000400338  0 SECTION LOCAL DEFAULT 7 
    8: 0000000000400340  0 SECTION LOCAL DEFAULT 8 
    9: 0000000000400360  0 SECTION LOCAL DEFAULT 9 
    10: 0000000000400378  0 SECTION LOCAL DEFAULT 10 
    11: 0000000000400390  0 SECTION LOCAL DEFAULT 11 
    12: 00000000004003b0  0 SECTION LOCAL DEFAULT 12 
    13: 00000000004003d0  0 SECTION LOCAL DEFAULT 13 
    14: 00000000004003e0  0 SECTION LOCAL DEFAULT 14 
    15: 0000000000400564  0 SECTION LOCAL DEFAULT 15 
    16: 0000000000400570  0 SECTION LOCAL DEFAULT 16 
    17: 0000000000400574  0 SECTION LOCAL DEFAULT 17 
    18: 00000000004005a8  0 SECTION LOCAL DEFAULT 18 
    19: 0000000000600e10  0 SECTION LOCAL DEFAULT 19 
    20: 0000000000600e18  0 SECTION LOCAL DEFAULT 20 
    21: 0000000000600e20  0 SECTION LOCAL DEFAULT 21 
    22: 0000000000600e28  0 SECTION LOCAL DEFAULT 22 
    23: 0000000000600ff8  0 SECTION LOCAL DEFAULT 23 
    24: 0000000000601000  0 SECTION LOCAL DEFAULT 24 
    25: 0000000000601020  0 SECTION LOCAL DEFAULT 25 
    26: 0000000000601030  0 SECTION LOCAL DEFAULT 26 
    27: 0000000000000000  0 SECTION LOCAL DEFAULT 27 
    28: 0000000000000000  0 FILE LOCAL DEFAULT ABS crtstuff.c 
    29: 0000000000600e20  0 OBJECT LOCAL DEFAULT 21 __JCR_LIST__ 
    30: 0000000000400410  0 FUNC LOCAL DEFAULT 14 deregister_tm_clones 
    31: 0000000000400450  0 FUNC LOCAL DEFAULT 14 register_tm_clones 
    32: 0000000000400490  0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux 
    33: 0000000000601030  1 OBJECT LOCAL DEFAULT 26 completed.7585 
    34: 0000000000600e18  0 OBJECT LOCAL DEFAULT 20 __do_global_dtors_aux_fin 
    35: 00000000004004b0  0 FUNC LOCAL DEFAULT 14 frame_dummy 
    36: 0000000000600e10  0 OBJECT LOCAL DEFAULT 19 __frame_dummy_init_array_ 
    37: 0000000000000000  0 FILE LOCAL DEFAULT ABS FIRST_PROG.c 
    38: 0000000000000000  0 FILE LOCAL DEFAULT ABS crtstuff.c 
    39: 0000000000400698  0 OBJECT LOCAL DEFAULT 18 __FRAME_END__ 
    40: 0000000000600e20  0 OBJECT LOCAL DEFAULT 21 __JCR_END__ 
    41: 0000000000000000  0 FILE LOCAL DEFAULT ABS 
    42: 0000000000600e18  0 NOTYPE LOCAL DEFAULT 19 __init_array_end 
    43: 0000000000600e28  0 OBJECT LOCAL DEFAULT 22 _DYNAMIC 
    44: 0000000000600e10  0 NOTYPE LOCAL DEFAULT 19 __init_array_start 
    45: 0000000000400574  0 NOTYPE LOCAL DEFAULT 17 __GNU_EH_FRAME_HDR 
    46: 0000000000601000  0 OBJECT LOCAL DEFAULT 24 _GLOBAL_OFFSET_TABLE_ 
    47: 0000000000400560  2 FUNC GLOBAL DEFAULT 14 __libc_csu_fini 
    48: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab 
    49: 0000000000601020  0 NOTYPE WEAK DEFAULT 25 data_start 
    50: 0000000000601030  0 NOTYPE GLOBAL DEFAULT 25 _edata 
    51: 0000000000400564  0 FUNC GLOBAL DEFAULT 15 _fini 
    52: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBC_ 
    53: 0000000000601020  0 NOTYPE GLOBAL DEFAULT 25 __data_start 
    54: 0000000000000000  0 NOTYPE WEAK DEFAULT UND __gmon_start__ 
    55: 0000000000601028  0 OBJECT GLOBAL HIDDEN 25 __dso_handle 
    56: 0000000000400570  4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used 
    57: 00000000004004f0 101 FUNC GLOBAL DEFAULT 14 __libc_csu_init 
    58: 0000000000601038  0 NOTYPE GLOBAL DEFAULT 26 _end 
    59: 00000000004003e0 42 FUNC GLOBAL DEFAULT 14 _start 
    60: 0000000000601030  0 NOTYPE GLOBAL DEFAULT 26 __bss_start 
    61: 00000000004004d6 11 FUNC GLOBAL DEFAULT 14 main 
    62: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 
    63: 0000000000601030  0 OBJECT GLOBAL HIDDEN 25 __TMC_END__ 
    64: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable 
    65: 0000000000400390  0 FUNC GLOBAL DEFAULT 11 _init 

请注意,进入37包含源文件的名称。如果您尝试diff荷兰国际集团的readelf -a输出,你得到一些非常有用的信息:

81c81 
< [28] .shstrtab   STRTAB   0000000000000000 0000189f 
--- 
> [28] .shstrtab   STRTAB   0000000000000000 000018a0 
86c86 
<  0000000000000207 0000000000000000   0  0  1 
--- 
>  0000000000000208 0000000000000000   0  0  1 
211c211 
<  37: 0000000000000000  0 FILE LOCAL DEFAULT ABS FIRST_PROG.c 
--- 
>  37: 0000000000000000  0 FILE LOCAL DEFAULT ABS SECOND_PROG.c 
258c258 
<  Build ID: 2c64961288049002e34a1f14e55d6c80dd96816c 
--- 
>  Build ID: 5425dec81aae53bd30e85fe94659d320bb774dcc 

这似乎是很多的这些差异归结为只是有源文件不同的名称。

所以我的正式答案是“这与整数文字没有任何关系,纯粹是编译不同名称文件的函数”。

+0

你是对的,我移动了文件,这样我就可以在同一个文件名中同时使用不同的东西,而且md5sum也是一样的。谢谢。我忘了编译原文。 –

相关问题