zl程序教程

您现在的位置是:首页 >  其他

当前栏目

自己动手构造编译系统:编译、汇编与链接1.3.3 汇编

2023-03-09 22:21:20 时间

1.3.3  汇编

  

            接着,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         $............  

Contents of section .rodata:

 0000  48656c6c  6f20576f  726c6421  00         Hello World!.  

Contents of section .comment:

 0000  00474343  3a202855  62756e74  752f4c69  .GCC: (Ubuntu/Li

 0010  6e61726f  20342e34  2e342d31  34756275  naro 4.4.4-14ubu

 0020  6e747535  2920342e  342e3500              ntu5) 4.4.5.   

 

Disassembly of section .text:

 

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,真正的符号地址只有在链接的时候才能确定。