Jakie są konwencje wywołujące wywołania systemu UNIX i Linux na i386 i x86-64

Poniższe linki wyjaśniają konwencje wywołań systemowych x86-32 zarówno dla Uniksa (BSD) jak i Linuksa:

Ale jakie są konwencje wywołań systemowych x86 - 64 na Unixie i Linuksie?

Author: Peter Cordes, 2010-03-29

4 answers

Zweryfikowałem je używając asemblera GNU (gas) na Linuksie.

Interfejs Jądra

X86-32 Linux System Call convention:

W x86-32 parametry wywołania systemu Linux są przekazywane za pomocą rejestrów. %eax dla syscall_number. %ebx, %ecx, %edx, %esi, %edi, % ebp są używane do przekazywania 6 parametrów do wywołań systemowych.

Wartość zwracana jest w %eax. Wszystkie pozostałe rejestry (w tym EFLAGS) są przechowywane w int $0x80.

I taked following fragment z Linux Assembly Tutorial ale wątpię w to. Jeśli ktoś może pokazać przykład, byłoby świetnie.

Jeśli jest więcej niż sześć argumentów, %ebx musi zawierać pamięć miejsce, w którym lista argumentów jest przechowywany - ale nie martw się o to ponieważ jest mało prawdopodobne, że użyjesz syscall z więcej niż sześcioma argumenty.

Dla przykładu i trochę więcej czytania, patrz http://www.int80h.org/bsdasm/#alternate-calling-convention

Istnieje szybszy sposób wykonywania 32-bitowych wywołań systemowych: używając sysenter. Jądro mapuje stronę pamięci do każdego procesu (vdso), ze stroną przestrzeni użytkownika sysenter, która musi współpracować z jądrem, aby móc znaleźć adres zwrotny. arg do rejestrowania mapowania jest takie samo jak dla int $0x80, ale zamiast tej instrukcji, kod powinien wywołać funkcję w vdso. (TODO: zaktualizuj to linkiem i / lub szczegółowe informacje).

X86-32[Free|Open|Net|DragonFly]BSD UNIX System Call convention:

Parametry są przekazywane na stos. Wypchnij parametry (ostatni parametr wypchnięty pierwszy) na stos. Następnie wypchnij dodatkowe 32-bitowe atrapy danych (w rzeczywistości nie są to atrapy danych. więcej informacji można znaleźć w poniższym linku), a następnie podać instrukcję wywołania systemowego int $0x80

Http://www.int80h.org/bsdasm/#default-calling-convention


X86-64 Linux System Call convention:

X86-64 Mac OS X jest podobny, ale inny . Do zrobienia: sprawdź co robi * BSD.

Zobacz sekcję: "A. 2 AMD64 Linux konwencje Jądra" System V Application Binary Interface amd64 Architecture Processor Supplement . Najnowsze wersje i386 i x86-64 System V psABIs można znaleźć podlinkowane z tej strony w repo opiekuna ABI . (Zobacz także tag wiki x86 Dla up-to-date Linki ABI i wiele innych dobrych rzeczy o x86 asm.)

Oto fragment z tej sekcji:

  1. aplikacje na poziomie użytkownika używają jako rejestrów całkowitych do przekazywania Sekwencja % rdi, %rsi, %rdx, %rcx, %r8 i %r9. interfejs jądra używa %rdi, %rsi, %rdx, %r10, % r8 i % R9.
  2. wywołanie systemowe odbywa się poprzez syscall Instrukcja . Ta blokuje %rcx i %r11, a także %rax, ale inne rejestry są zachowane.
  3. numer syscall musi zostać przekazany w rejestrze %rax.
  4. wywołania systemowe są ograniczone do sześciu argumentów, żaden argument nie jest przekazywany bezpośrednio na stosie.
  5. powrót z syscall, register % rax zawiera wynik system-call. Wartość z zakresu od -4095 do -1 wskazuje błąd, to jest -errno.
  6. tylko wartości klasy INTEGER lub class MEMORY są przekazywane do jądra.

Pamiętaj, że to z Specyficzny dla Linuksa dodatek do ABI, a nawet dla Linuksa jest informacyjny a nie normatywny. (Ale w rzeczywistości jest to dokładne.)

Interfejs Użytkownika

Konwencja wywołania funkcji X86-32:

W x86-32 parametry były przekazywane na stosie. Ostatni parametr był wpychany najpierw na stos, aż wszystkie parametry zostaną wykonane, a następnie została wykonana Instrukcja call. Jest to używane do wywoływania funkcji biblioteki C (libc) w Linuksie z assembly.


X86-64 Konwencja wywołania funkcji:

X86-64 przekazuje args w rejestrach, co jest bardziej wydajne niż konwencja args stosu i386 System V. Pozwala to uniknąć opóźnień i dodatkowych instrukcji przechowywania args do pamięci (cache), a następnie ładowania ich ponownie w callee. Działa to dobrze, ponieważ dostępnych jest więcej rejestrów i jest lepsze dla nowoczesnych wysokowydajnych procesorów, w których liczą się opóźnienia i realizacja poza zamówieniem. (I386 ABI jest bardzo stary).

W tym nowy mechanizm: najpierw parametry są podzielone na klasy. Klasa każdego parametru określa sposób, w jaki jest przekazywany do wywołanej funkcji.

Pełne informacje można znaleźć w : "3.2 Sekwencja wywołania funkcji" System V Application Binary Interface amd64 Architecture Processor Supplement , który brzmi częściowo:

Po zaklasyfikowaniu argumentów, rejestry zostają przypisane (w kolejności od lewej do prawej) za przejście jako następuje:

  1. jeśli klasa jest pamięcią, podaj argument na stosie.
  2. jeśli klasa jest liczbą całkowitą, następny dostępny rejestr w zależności od tego, która z tych wartości jest większa,]}

Więc %rdi, %rsi, %rdx, %rcx, %r8 and %r9 są rejestrami w kolejności używanymi do przekazywania parametrów integer/pointer (tj. klasy INTEGER) do dowolnej funkcji libc z assembly. %rdi jest używane dla pierwszego parametru INTEGER. %rsi dla 2nd, %rdx dla 3rd i tak dalej. Then call należy udzielić instrukcji. Stos (%rsp) musi być wyrównany do 16B podczas wykonywania call.

Jeśli jest więcej niż 6 parametrów INTEGER, 7. parametr INTEGER i Później są przekazywane na stosie. (Dzwoniący wyskakuje, tak samo jak x86-32.)

Pierwsze 8 zmiennoprzecinkowych argów jest przekazywanych w %xmm0-7, później na stosie. Nie ma rejestrów wektorowych zachowanych do wywołania. (Funkcja z mieszanką argumentów FP i integer może mieć więcej niż 8 całkowitych argumentów rejestru.)

Variadic functions (like printf) zawsze potrzebujesz %al = numer args rejestru FP.

Istnieją reguły, kiedy pakować struktury do rejestrów (rdx:rax po powrocie) vs. w pamięci. Zobacz ABI po szczegóły i sprawdź wyjście kompilatora, aby upewnić się, że Twój kod zgadza się z kompilatorami co do tego, jak coś powinno zostać przekazane/zwrócone.

 181
Author: claws,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-15 18:37:13

Może szukasz ABI x86_64?

Jeśli nie jest to dokładnie to, czego szukasz, użyj 'x86_64 abi' w preferowanej wyszukiwarce, aby znaleźć alternatywne odniesienia.

 11
Author: Jonathan Leffler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-29 05:56:21

Konwencje wywołania definiują sposób przekazywania parametrów w rejestrach podczas wywoływania lub wywoływania przez inny program. A najlepszym źródłem tej konwencji są standardy ABI zdefiniowane dla każdego z tych urządzeń. Dla ułatwienia kompilacji, ten sam ABI jest również używany przez program userspace i kernel. Linux / Freebsd podąża za tym samym ABI dla x86-64 i innym zestawem dla 32-bitów. Ale x86-64 ABI Dla Windows różni się od Linuksa / FreeBSD. I generalnie ABI nie rozróżnia wywołanie systemowe vs zwykłe "wywołania funkcji". Ie, oto szczególny przykład wywoływania konwencji x86_64 i jest to takie samo zarówno dla przestrzeni użytkownika Linuksa, jak i jądra: http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/ (zwróć uwagę na ciąg A,b,c,D,e, f parametrów):

Dobre renderowanie wywołujących konwencje vs wykorzystanie rejestrów

Wydajność jest jedną z przyczyn tych ABI (np. przekazywanie parametrów przez rejestry zamiast zapisywania do stosów pamięci)

Dla ARM istnieje wiele ABI:

Http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.swdev.abi/index.html

Https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/iPhoneOSABIReference.pdf

Konwencja ARM64:

Http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf

Dla Linuksa na PowerPC:

Http://refspecs.freestandards.org/elf/elfspec_ppc.pdf

Http://www.0x04.net/doc/elf/psABI-ppc64.pdf

I dla osadzonych jest PPC EABI:

Http://www.freescale.com/files/32bit/doc/app_note/PPCEABI.pdf

Ten dokument jest dobrym przeglądem wszystkich różnych konwencji:

Http://www.agner.org/optimize/calling_conventions.pdf

 9
Author: Peter Teoh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-23 12:26:39

Oprócz linku, który Jonathan Leffler podaje w swojej odpowiedzi, przydatne mogą być również konwencje wywoływania plików PDF Agnera Foga.

 4
Author: PhiS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-29 08:08:01