<b>1.3.3 彙編</b>
接着,gcc使用彙編器對hello.s進行彙編,指令如下:
$gcc –c hello.s
–o hello.o
生成的目标檔案hello.o,linux下稱之為可重定位目标檔案。目标檔案無法使用文本編輯器直接檢視,但是我們可以使用gcc自帶的工具objdump指令分析它的内容,指令格式如下:
$objdump –sd
hello.o
輸出目标檔案的主要段的内容與反彙編代碼如下:
hello.o: file format elf32-i386
contents of
section .text:
0000
5589e583 e4f083ec 10b80000
00008904 u...............
0010
24e8fcff ffffb800 000000c9
c3 $............
section .rodata:
48656c6c 6f20576f 726c6421
00 hello world!.
section .comment:
00474343 3a202855 62756e74
752f4c69 .gcc: (ubuntu/li
6e61726f 20342e34 2e342d31
34756275 naro 4.4.4-14ubu
0020
6e747535 2920342e 342e3500 ntu5) 4.4.5.
disassembly of
00000000
<main>:
0: 55 push %ebp
1: 89
e5 mov %esp,%ebp
3: 83
e4 f0 and $0xfffffff0,%esp
6: 83
ec 10 sub $0x10,%esp
9: b8
00 00 00 00 mov $0x0,%eax
e: 89
04 24 mov %eax,(%esp)
11: e8
fc ff ff ff call 12
<main+0x12>
16: b8
00 00 00 00 mov $0x0,%eax
1b: c9 leave
1c: c3 ret
從資料段二進制資訊的ascii形式的顯示中,我們看到了彙編語言内定義的字元串資料“hello world !”。代碼段的資訊和彙編檔案代碼資訊基本吻合,但是我們發現了很多不同之處。比如彙編檔案内的指令“movl $.lc0, %eax”中的符号.lc0的位址(字元串“hello
world !”的位址)被換成了0。指令“call printf ”内符号printf的相對位址被換成了0xfffffffc,即call指令操作數部分的起始位址。
這些差別本質來源于彙編語言符号的引用問題。由于彙編器在處理目前檔案的過程中無法獲悉符号的虛拟位址,是以臨時将這些符号位址設定為預設值0,真正的符号位址隻有在連結的時候才能确定。