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

mah*_*esh 8 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
Run Code Online (Sandbox Code Playgroud)

一点低级解释将受到高度赞赏.

提前致谢.

Dav*_*veS 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

戴夫.