2013-08-06 8 views
6

Chciałbym wiedzieć, jak działają programy, aby zrobić to jak okiełznane kości, jak to tylko możliwe.Dlaczego program złożenia działa tylko po połączeniu z crt1.o crti.o i crtn.o?

Właśnie dowiedziałem się, jak zainstalować kod dla x86_64 za pomocą funkcji wprintf (ustalono, że szerokie znaki są 32-bitowe). wszystko co musiałem zrobić to link do libc (-lc).

Próbuję złożyć kod dla 32-bitowego robiąc o tym samym rzecz, ale potknąłem się całkiem sporo. Ostatecznie użyłem gcc do połączenia (i zmieniłem _start: na main :). Tak więc zrobiłem linkowanie za pomocą ld i zawarłem crt1.o crti.o i crtn.o. Wtedy mój program działał (nie wydrukował niczego wcześniej) Więc moje pytanie brzmi, czy mogę zrobić coś w moim kodzie, aby wyeliminować potrzebę tych 3 innych plików obiektów (i oczywiście powrócić do _start: zamiast głównej :) ?

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 

i uruchamiając następujące

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, a wyjście jest po prostu japoński hiragana (MA) ま (zawiadomienie nie ma przerwy w linii tak drukuje przed monitem)

+0

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

Odpowiedz

8

Oto, co pliki robią za Ciebie. Są środowiskiem c-runtime i instalacją, które prowadzą do systemu operacyjnego.

crt1.o Nowszy styl początkowego kodu środowiska wykonawczego. Zawiera symbol _start, który ustawia env z argc/argv/libc _init/libc _fini przed przejściem do głównej biblioteki libc. glibc nazywa ten plik "start.S".

crti.o Określa prologowym funkcyjną; _init w sekcji .init i _fini w sekcji .fini. glibc nazywa to "initfini.c".

crtn.o Definiuje epilog funkcji. glibc nazywa to "initfini.c".

Istnieje doskonały kod zapisu i przykładowy, który można znaleźć na następującej stronie internetowej http://wiki.osdev.org/Creating_a_C_Library dla każdej z powyższych bibliotek.

+0

dobrze twój link pokazuje sporo tego, czego mi brakuje. Niestety opiera się na konwencjach wywoływania x86_64. Zastanawiam się, gdzie argc i argv mają być w programie 32-bitowym. Dlaczego mój 64-bitowy program nie potrzebował tych plików, ale mój 32-bitowy? – Craig

+0

Założę się, że łącznik 32 i 64 pobiera różne wartości domyślne, ale nie jestem pewien. Napotkałem różnice między linkerami w toolchainach. –

+0

Kompilowanie bez libc (http://stackoverflow.com/questions/2548486/compiling-without-libc) ma dodatkowe dobre informacje. –

0

W 3-bitowym systemie Linux są na stosie. Przy uruchomieniu 0 (% esp) zawiera argc. Przy 4 (% esp) znajdziesz wskaźnik do nazwy programu (który jest zawarty w argc). Następnie pojawia się zestaw wskaźników do argumentów, zakończony wskaźnikiem NULL. Następnie pojawia się kolejny zestaw wskaźników NULL do zmiennych systemowych. Powiedziano mi, że może ich być ponad 200 !!

Shiarta

Powiązane problemy