链接器如何解析汇编代码中的符号

时间:2009-07-29 09:02:09

标签: c++ c assembly linker

我想知道链接器如何解析以下汇编代码中的printf符号。

#include<stdio.h>
void main()
{
     printf("Hello ");
}




    .file   "test.c"
    .def    ___main;    .scl    2;  .type   32; .endef
    .section .rdata,"dr"
LC0:
    .ascii "Hello \0"
    .text
.globl _main
    .def    _main;  .scl    2;  .type   32; .endef
_main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    andl    $-16, %esp
    movl    $0, %eax
    addl    $15, %eax
    addl    $15, %eax
    shrl    $4, %eax
    sall    $4, %eax
    movl    %eax, -4(%ebp)
    movl    -4(%ebp), %eax
    call    __alloca
    call    ___main
    movl    $LC0, (%esp)
    **call  _printf**
    leave
    ret
    .def    **_printf**;    .scl    3;  .type   32; .endef

低级别解释将受到高度赞赏。

提前致谢。

4 个答案:

答案 0 :(得分:17)

假设ELF文件格式,汇编器将在目标文件中生成未定义的符号引用。这看起来像这样:

Symbol table '.symtab' contains 11 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1
     3: 00000000     0 SECTION LOCAL  DEFAULT    3
     4: 00000000     0 SECTION LOCAL  DEFAULT    4
     5: 00000000     0 SECTION LOCAL  DEFAULT    5
     6: 00000000     0 SECTION LOCAL  DEFAULT    6
     7: 00000000     0 SECTION LOCAL  DEFAULT    7
     8: 00000000    52 FUNC    GLOBAL DEFAULT    1 main
     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
    10: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND exit

它还将创建一个重定位条目,指向代码映像的一部分,需要由链接器使用正确的地址进行更新。它看起来像这样:

tool2 0>readelf -r test.o

Relocation section '.rel.text' at offset 0x358 contains 3 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0000001f  00000501 R_386_32          00000000   .rodata
00000024  00000902 R_386_PC32        00000000   printf
00000030  00000a02 R_386_PC32        00000000   exit

然后链接器的工作是遍历重定位表,用最终的符号地址修复代码映像。

有一本很好的书,但我现在找不到详细信息(而且已经绝版了)。但是,这似乎有用:http://www.linuxjournal.com/article/6463

戴夫。

答案 1 :(得分:1)

关于链接过程的好书,请参阅Linkers&amp; John Levine的装载机。您可以使用HTML格式here获取稿件章节。

答案 2 :(得分:1)

Ulrich Drepper撰写的How To Write Shared Libraries文章可能对您有所帮助。 Ulritch Linux glibc维护者,他是ELF的权威。

尽管本文是关于如何编写共享库以及如何导出或不导出符号,但它解释了如何在具有ELF格式的exe文件中动态解析这些符号。

我想它可能会回答你的问题。

答案 3 :(得分:1)

链接器的另一个好资源是这一系列文章:http://www.google.fr/search?q=site%3Awww.airs.com%2Fblog%2Farchives+%22linkers+part%22