2010-07-30 11 views
8

uczę asm na Linuksie (noobuntu 10.04) Mam następujący kod off: http://asm.sourceforge.net/intro/hello.htmlZgromadzenie, hello world pytanie

section .text 
global _start ;must be declared for linker (ld) 

_start: ;tell linker entry point 

mov edx,len ;message length 
mov ecx,msg ;message to write 
mov ebx,1 ;file descriptor (stdout) 
mov eax,4 ;system call number (sys_write) 
int 0x80 ;call kernel 

mov eax,1 ;system call number (sys_exit) 
int 0x80 ;call kernel 

section .data 

msg db 'Hello, world!',0xa ;our dear string 
len equ $ - msg ;length of our dear string 

To proste Hello World. Działa na Linuksie + wywołuje jądro bezpośrednio (podobno). Czy ktoś może wyjaśnić, co naprawdę się tutaj dzieje? Myślę, że odczytuje liczby całkowite w rejestrach ebx e2 & ekx, edx danych i określa wywołanie systemowe, gdy wywoływane jest jądro. Jeśli tak, to czy różne kombinacje liczb całkowitych definiują różne wywołania systemowe, gdy int 0x80 jest wywoływane?

Nie jestem dobry ze stronami man, ale przeczytałem wszystkie powiązane, które mogę znaleźć, czy jakakolwiek strona podręcznika mówi mi, jakie kombinacje definiują jakie linie boczne?

KAŻDA pomoc jest doceniana. Linia linią wyjaśnieniem byłoby niesamowite ... -dzięki z góry Jeremy

Odpowiedz

7

Po wywołaniu int 0x80, kernel sprawdza wartość rejestru eax określić funkcję, którą chcesz zadzwonić (jest to " numer syscall "). W zależności od tej liczby reszta rejestrów jest interpretowana jako oznaczająca określone rzeczy. sys_write wezwanie spodziewa rejestrów, które mają być ustawione w następujący sposób:

  • eax zawiera 4
  • ebx zawiera deskryptor pliku
  • ecx zawiera adres danych napisać
  • edx zawiera liczbę bajty

Aby uzyskać więcej informacji, zobacz Linux System Calls.

+0

Bardzo dziękuję, to było moje podejrzenie i niemniej pomocna ... Czy możesz mi powiedzieć, gdzie mogę dowiedzieć się więcej? Czy są to liczby całkowite ze spisu w stronach podręcznika? – Jeremy

+0

Musisz zagłębić się głęboko w pliki nagłówkowe źródła Linux, aby znaleźć numery połączeń systemowych. W tej chwili nie mam pod ręką komputera z systemem Linux, więc nie mogę podać dokładnej lokalizacji, ale jest to coś w rodzaju 'include/asm/syscall.h' w drzewie źródeł jądra. –

+0

dziękuję bardzo, byłeś v. Pomocny. – Jeremy

0

Istnieje zbyt wiele wywołań systemowych, aby każda instrukcja montażu była inna.

Zamiast tego należy wywołać instrukcję TRAP. Wartość eax określa, które wywołanie systemowe będzie wywoływane. Pozostałe rejestry są argumentami wywołania systemowego.

Wywołania systemowe są wymienione wewnątrz jądra.

+0

Dziękuję. Gdzie dokładnie patrzę na wywołania systemowe w jądrze? – Jeremy

2
section .text 
global _start ;must be declared for linker (ld) 

To tylko header materiał, sekcja „text” z programu montażowego jest tylko instrukcje maszynowe (w porównaniu do danych, tylko do odczytu danych, a sekcje BSS). Linia global jest podobna do stwierdzenia, że ​​funkcja _start jest "publiczna".

_start: ;tell linker entry point 

mov edx,len ;message length 
mov ecx,msg ;message to write 
mov ebx,1 ;file descriptor (stdout) 
mov eax,4 ;system call number (sys_write) 
int 0x80 ;call kernel 

Od komentarzach wiemy, że mamy do czynienia z funkcją sys_write, więc możemy man 2 write, aby uzyskać szczegóły. Prototyp C daje następujące parametry: fd, *buf i count. Zaczynając od% ebx widzimy, że te dopasowania (% ebx = fd,% ecx = string do zapisu, a% edx = długość łańcucha). Następnie, ponieważ jesteśmy procesem użytkownika, musimy poprosić jądro o wykonanie wyniku. Odbywa się to poprzez interfejs SYSCALL, a funkcja write() jest (najwyraźniej) z liczbą 4. INT 0x80 jest przerwaniem programowym, które wywołuje procedurę SYSCALL jądra systemu Linux.

Możesz znaleźć rzeczywiste numery wszystkich plików systemowych w plikach nagłówkowych systemu Linux (zakładając, że masz je zainstalowane). W moim systemie sprawdziłem /usr/include/sys/syscall.h prowadząc do /usr/include/asm/unistd.h, a następnie na /usr/include/asm-i386/unistd.h. Gdzie (widzę), #define __NR_write 4.

mov eax,1 ;system call number (sys_exit) 
int 0x80 ;call kernel 

jak w ostatnich dwóch wierszach poprzedniego segmentu, to po prostu ładuje id syscall i robi przerwanie oprogramowania, aby wyjść z programu (usunąć to mapowanie pamięci i czyszczenie).

section .data 

msg db 'Hello, world!',0xa ;our dear string 
len equ $ - msg ;length of our dear string 

To jest sekcja danych, po prostu opisuje zmienne używane w naszym programie.

+0

Najbardziej przydatna odpowiedź. Dziękuję bardzo za poświęcony czas. – Jeremy