天天看點

自己動手構造編譯系統:編譯、彙編與連結1.3.3 彙編

<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

&lt;main&gt;:

    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

&lt;main+0x12&gt;

   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,真正的符号位址隻有在連結的時候才能确定。

繼續閱讀