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
戴夫.