2009-07-29 9 views
8

Quería saber cómo el enlazador resuelve el símbolo de printf en el siguiente código de ensamblaje.Cómo el enlazador resuelve el símbolo en el código de ensamblaje

#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 

Poco de nivel bajo Explicación será muy apreciada.

Gracias de antemano.

+1

¡Una gran pregunta que no se ha formulado lo suficiente y que ha generado muchas preguntas de "símbolos sin resolver" en SO! – xtofl

Respuesta

17

Suponiendo que el formato de archivo ELF, el ensamblador generará una referencia de símbolo indefinido en el archivo de objeto. Esto va a tener este aspecto:

 
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 

También va a crear una entrada de reubicación para apuntar a la parte de la imagen de código que necesita ser actualizado por el enlazador con la dirección correcta. Se verá así: trabajo

 
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 

del enlazador es entonces que caminar a través de la tabla de reubicación de la imagen de código de arreglar con las direcciones símbolo final.

Hay un libro excelente, pero no puedo encontrar los detalles en este momento (y está agotado). Sin embargo, esto parece que puede ser útil: http://www.linuxjournal.com/article/6463

Dave.

+0

Impresionante respuesta Dave. Muy claramente delineado. Muchas gracias. Sería genial para ti si pudieras recordarte y dejarme ese libro también :) – mahesh

1

Para obtener un excelente libro sobre el proceso de enlace, consulte Enlazadores & Cargadores de John Levine. Puede obtener los capítulos del manuscrito en formato HTML here.

1

Un documento que podría ayudarlo es How To Write Shared Libraries por Ulrich Drepper. Ulritch es el mantenedor de Linux glibc y es una autoridad en ELF.

Aunque este documento trata sobre cómo escribir bibliotecas compartidas y cómo exportar o no exportar símbolos, explica cómo esos símbolos se resuelven dinámicamente dentro de un archivo exef con formato ELF.

Supongo que podría responder a su pregunta.

+0

Gracias por el enlace :). Se ve bien. – mahesh

Cuestiones relacionadas