2013-08-06 5 views
6

Mi piace sapere come funzionano i programmi in modo da renderlo il più semplice possibile. Mi diverto con il montaggio.Perché un programma di assemblaggio funziona solo se collegato a crt1.o crti.o e crtn.o?

Ho appena scoperto come assemblare il codice per x86_64 utilizzando la funzione wprintf (i caratteri wide trovati sono 32 bit). tutto quello che dovevo fare era il collegamento a libc (-lc).

Sto cercando di assemblare il codice per fare a 32 bit la stessa cosa ma sono inciampato un po '. Alla fine ho usato gcc per fare il collegamento (e cambiato il _start: to main :). Allora ho fatto il collegamento io stesso usando ld e ho incluso crt1.o crti.o e crtn.o. Quindi il mio programma ha funzionato (non avrebbe stampato nulla prima) Quindi la mia domanda è, posso fare qualcosa nel mio codice per eliminare la necessità di questi altri 3 file oggetto (e naturalmente tornare a _start: invece di main :) ?

test_lib.S

.section .data 
locale: 
    .string "" 
    .align 4 
printformat: 
    .long '%','l','c',0 

.section .text 
.global main 
main: 

pushl $locale 
pushl $6 
call setlocale 
pushl $12414 
pushl $printformat 
call wprintf 
pushl $2 
call exit 

e eseguendo i seguenti

as --32 test_lib.S -o test_lib.o 
ld -m elf_i386 -L/lib/ -L/usr/lib/ -I/lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o -lc /usr/lib/crtn.o test_lib.o -o test_lib 
./test_lib 

oh e l'uscita è semplicemente un hiragana giapponese (ma) ま (avviso non v'è alcuna interruzione di linea così esso stampa prima del prompt)

+0

http://stackoverflow.com/questions/3577922/how-to-link-a-gas-assembly-file-as-ac-program-with-ld-without-using-gcc –

risposta

8

Ecco cosa fanno i file per te. Sono l'ambiente c-runtime e l'installazione che si collegano al sistema operativo.

crt1.o Nuovo stile del codice runtime iniziale. Contiene il simbolo _start che imposta env con argc/argv/libc _init/libc _fini prima di passare alla main di libc. glibc chiama questo file 'start.S'.

crti.o Definisce la funzione prolog; _init nella sezione .init e _fini nella sezione .fini. glibc chiama questo 'initfini.c'.

crtn.o Definisce la funzione epilog. glibc chiama questo 'initfini.c'.

È disponibile un eccellente codice di scrittura e di esempio sul seguente sito Web http://wiki.osdev.org/Creating_a_C_Library per ciascuna delle librerie di cui sopra.

+0

bene il tuo link mostra un po 'di quello che mi manca. Sfortunatamente si basa sulle convenzioni di chiamata di x86_64. Mi chiedo dove dovrebbero essere argc e argv in un programma a 32 bit. Inoltre, perché il mio programma a 64 bit non aveva bisogno di questi file, ma il mio a 32 bit lo ha fatto? – Craig

+0

Suppongo che il 32 vs 64 linker stia selezionando valori diversi, ma non ne sono sicuro. Ho riscontrato differenze tra i linker in toolchain. –

+0

La compilazione senza libc (http://stackoverflow.com/questions/2548486/compiling-without-libc) ha ulteriori informazioni utili. –

0

In Linux a 3 bit, sono in pila. All'avvio, 0 (% esp) contiene argc. A 4 (% esp), troverai un puntatore al nome del programma (che è incluso in argc). Dopodiché arriva una serie di puntatori agli argomenti, conclusi con un puntatore NULL. Dopo di ciò, arriva un altro array di puntatori alle variabili di sistema, concluso da NULL. Mi è stato detto che potrebbero esserci oltre 200 di loro !!

Shiarta

Problemi correlati