Ich verifizierte diese mit GNU Assembler (Gas) auf Linux.
Kernel-Schnittstelle
x86-32 Linux Systemaufruf Konvention:
In x86-32 Parameter für Linux-Systemaufruf verwenden Registern übergeben. %eax
für syscall_number. % ebx,% ecx,% edx,% esi,% edi,% ebp werden verwendet, um 6 Parameter an Systemaufrufe zu übergeben.
Der Rückgabewert ist in %eax
. Alle anderen Register (einschließlich EFLAGS) bleiben über die int $0x80
hinweg erhalten.
Ich nahm folgendes Schnipsel von der Linux Assembly Tutorial, aber ich bin zweifelhaft darüber. Wenn jemand ein Beispiel zeigen kann, wäre es großartig.
Bei mehr als sechs Argumente, %ebx
müssen die Speicher Standort enthalten, in dem die Liste der Argumente gespeichert ist - aber keine Sorge über diese , weil es unwahrscheinlich, dass Sie ein syscall verwenden werden mit mehr als sechs Argumente.
Für ein Beispiel und ein wenig mehr lesen, finden Sie in http://www.int80h.org/bsdasm/#alternate-calling-convention
Es schnellen Weg ist, 32-Bit-System machen Anrufe: mit sysenter
. Der Kernel ordnet jedem Prozess (dem vdso) eine Seite mit Speicher zu, mit der User-Space-Seite von sysenter
, die mit dem Kernel kooperieren muss, damit er die Rückkehradresse finden kann. arg to register mapping ist das gleiche wie für int $0x80
, aber statt dieser Anweisung sollte der Code eine Funktion im vdso aufrufen. (TODO: Aktualisieren Sie dies mit einem Link und/oder spezifischen Informationen).
x86-32 [Free | Open | Net | DragonFly] BSD UNIX-Systemaufruf Konvention:
Parameter werden auf dem Stack übergeben. Drücken Sie die Parameter (letzter Parameter zuerst gedrückt) auf den Stapel. Drücken Sie dann eine zusätzliche 32-Bit-Dummy-Daten (Es ist nicht wirklich Dummy-Daten. Verweisen für weitere Informationen zu folgenden Link) und dann ein Systemaufruf Anweisung geben int $0x80
http://www.int80h.org/bsdasm/#default-calling-convention
x86-64 Linux Systemanrufkonvention:
x86-64 Mac OS X is similar but different. TODO: Überprüfen Sie, was * BSD tut.
Siehe Abschnitt: "A.2 AMD64 Linux Kernel Conventions" von System V Application Binary Interface AMD64 Architecture Processor Supplement. Die neuesten Versionen der iSeries i386 und x86-64 System V psABIs finden Sie unter linked from this page in the ABI maintainer's repo. (Siehe auch x86 Tag Wiki für up-to-date ABI Links und viele andere gute Sachen über x86 nh.)
Hier ist der Ausschnitt aus diesem Abschnitt:
- Anwendungen auf Benutzerebene Verwenden Sie als Ganzzahlregister zum Übergeben der Sequenz% rdi,% rsi,% rdx,% rcx, % r8 und% r9. Die Kernelschnittstelle verwendet% rdi,% rsi,% rdx,% r10,% r8 und% r9.
- Ein Systemanruf erfolgt über die
syscall
Anweisung. Diese Clobber% rcx und% r11, sowie% rax, aber andere Register bleiben erhalten.
- Die Nummer des Syscalls muss im Register% rax übergeben werden.
- Systemaufrufe sind auf sechs Argumente beschränkt, es wird kein Argument direkt auf dem Stapel übergeben.
- Rückkehr vom Systemaufruf, Register% Rax enthält das Ergebnis der Systemaufruf. Ein Wert im Bereich zwischen -4095 und -1 zeigt einen Fehler an, es ist
-errno
.
- Nur Werte der Klasse INTEGER oder der Klasse MEMORY werden an den Kernel übergeben.
dieses Denken Sie daran, ist der Linux-spezifischen Anhang des ABI, und auch für Linux ist es nicht normative informativ. (Aber es ist in der Tat genau.)
Benutzeroberfläche
x86-32 Funktion Aufrufkonvention:
In x86-32 Parameter wurden auf Stack übergeben. Der letzte Parameter wurde zuerst auf den Stapel geschoben, bis alle Parameter fertig sind und dann die Anweisung call
ausgeführt wurde. Dies wird zum Aufrufen von C-Bibliotheks (libc) -Funktionen unter Linux von Assembly verwendet.
x86-64 Funktion Aufrufkonvention:
x86-64 args in Registern übergibt, die als herkömmliche i386 System V Stack args effizienter ist. Es vermeidet die Latenz und zusätzliche Anweisungen zum Speichern von Argumenten im Speicher (Cache) und dann wieder zum Laden in den Aufrufer. Dies funktioniert gut, da mehr Register verfügbar sind, und besser für moderne Hochleistungs-CPUs, bei denen Latenz und Out-of-Order-Ausführung von Bedeutung sind. (Der i386 ABI ist sehr alt).
In diesem neuen Mechanismus: Zuerst sind die Parameter in Klassen unterteilt. Die Klasse jedes Parameters bestimmt die Art und Weise, in der er an die aufgerufene Funktion übergeben wird.
Ausführliche Informationen finden Sie unter: „3.2 Funktion Aufrufsequenz“ von System V Application Binary Interface AMD64 Architecture Processor Supplement, die zum Teil lautet:
Sobald Argumente klassifiziert sind, erhalten die Register zugeordnet (in von links nach rechts Reihenfolge) für wie folgt verläuft:
- Wenn die Klasse Speicher befindet, auf dem Stapel das Argument übergeben.
- Wenn die Klasse INTEGER, das nächste verfügbare Register der Sequenz% rdi,% rsi,% RDX,% rcx,% r8 und% r9 verwendet wird
So %rdi, %rsi, %rdx, %rcx, %r8 and %r9
sind die Register in der Reihenfolge verwendet, um Integer/Zeiger (dh INTEGER-Klasse) -Parameter zu einer beliebigen libc-Funktion aus Assembly übergeben. % rdi wird für den ersten INTEGER-Parameter verwendet. % rsi für 2.,% rdx für 3. und so weiter. Dann sollte call
Anweisung gegeben werden. Der Stapel (%rsp
) muss 16B-ausgerichtet sein, wenn call
ausgeführt wird.
Wenn mehr als 6 INTEGER-Parameter vorhanden sind, werden der siebte INTEGER-Parameter und später auf dem Stapel übergeben. (Der Anrufer erscheint wie bei x86-32.)
Die ersten 8 Fließkomma-Argumente werden in% xmm0-7 übergeben, später im Stapel. Es gibt keine Call-Preserved-Vektorregister. (Eine Funktion mit einer Mischung aus FP- und Integer-Argumenten kann mehr als 8 Registerregister enthalten.)
Variadic-Funktionen (like printf
) müssen immer %al
= die Anzahl der FP-Registerargumente.
Es gibt Regeln dafür, wann man Strukturen in Register (rdx:rax
bei Rückgabe) im Speicher packen muss. Weitere Informationen finden Sie in der ABI. Überprüfen Sie die Compilerausgabe, um sicherzustellen, dass Ihr Code mit Compilern übereinstimmt, wie etwas weitergegeben/zurückgegeben werden soll.
Es gibt keine "Standard" für Unix-Konventionen aufruft. Für Linux sicher, aber ich bin mir sicher, dass Solaris, OpenBSD, Linux und Minix wahrscheinlich unterschiedliche Aufrufkonventionen haben und sie sind alle unix. – Earlz
Das ist nicht ganz richtig - es gibt eine Reihe von UNIX-ABIs für die meisten Maschinentypen, die es C-Compilern ermöglichen, Interoperabilität zu erreichen. C++ - Compiler haben ein größeres Problem. –
Sie beide sind richtig. Ich suche nach FreeBSD & Linux. – claws