2010-03-29 3 views
96

eines Links erklären x86-32 Systemaufruf Konventionen sowohl für UNIX (BSD Geschmack) & Linux:Was die Aufrufkonventionen für UNIX und Linux-System sind fordert i386 und x86-64

Aber was sind die x86-64 Systemaufruf Konventionen sowohl auf UNIX & Linux?

+0

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

+1

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. –

+0

Sie beide sind richtig. Ich suche nach FreeBSD & Linux. – claws

Antwort

163

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 Tag Wiki für up-to-date ABI Links und viele andere gute Sachen über x86 nh.)

Hier ist der Ausschnitt aus diesem Abschnitt:

  1. 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.
  2. Ein Systemanruf erfolgt über die syscall Anweisung. Diese Clobber% rcx und% r11, sowie% rax, aber andere Register bleiben erhalten.
  3. Die Nummer des Syscalls muss im Register% rax übergeben werden.
  4. Systemaufrufe sind auf sechs Argumente beschränkt, es wird kein Argument direkt auf dem Stapel übergeben.
  5. 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.
  6. 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:

  1. Wenn die Klasse Speicher befindet, auf dem Stapel das Argument übergeben.
  2. 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.

+0

In Linux 32 "alle Register außer ax bx CD dx si di bp sind erhalten". Ich kann mir nichts vorstellen ... –

+0

Amd64, wenn es mehr als 6 Parameter gibt und sie auf dem Stapel übergeben werden, wer ist verantwortlich für das Aufräumen des Stapels nach dem Anruf, Anrufer oder Anrufer? –

+1

@ Nicolás: Anrufer reinigt den Stapel. Ich habe die Antwort mit weiteren Details zur Funktionsaufrufkonvention aktualisiert. –

11

Vielleicht suchen Sie nach dem x86_64 ABI?

Wenn das nicht genau, was Sie wollen, verwenden Sie 'x86_64 abi' in Ihrer bevorzugten Suchmaschine alternative Referenzen zu finden.

+3

eigentlich will ich nur die System Call Convention. esp für UNIX (FreeBSD) – claws

+3

@claws: Die Systemaufrufkonvention ist ein Teil des ABI. –

+1

ja. Ich bin zur Kernel-Entwicklung jedes einzelnen Betriebssystems gegangen und habe sie danach gefragt. Sie haben mir gesagt, ich solle in die Quelle schauen und herausfinden. Ich verstehe nicht, ohne zu dokumentieren, wie können sie gerade anfangen zu entwickeln? Also habe ich eine Antwort aus gesammelten Informationen hinzugefügt, in der Hoffnung, dass andere die restlichen Details ausfüllen. – claws

4

Zusätzlich zu dem Link, den Jonathan Leffler in seiner Antwort bietet, kann auch Agner Fogs Calling Conventions pdf für Sie nützlich sein.

+0

eigentlich will ich nur die System Call Convention. – claws

8

Aufrufkonventionen definieren, wie Parameter in den Registern übergeben werden, wenn sie von einem anderen Programm aufgerufen oder aufgerufen werden. Und die beste Quelle für diese Konvention sind die ABI-Standards, die für jede dieser Hardware definiert sind. Zur Vereinfachung der Kompilierung wird das gleiche ABI auch von Userspace und Kernel-Programm verwendet. Linux/Freebsd folgen dem gleichen ABI für x86-64 und einem anderen Satz für 32-Bit. Aber x86-64 ABI für Windows unterscheidet sich von Linux/FreeBSD. Und im Allgemeinen unterscheidet ABI nicht zwischen Systemaufruf und normalen "Funktionsaufrufen". Dh, hier ist ein besonderes Beispiel für x86_64 Aufrufkonventionen und es ist für beide gleich Linux User-Space und Kernel: http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/ (man beachte die Reihenfolge a, b, c, d, e, f des Parameters):

A good rendering of calling conventions vs registers usage

Leistung ist einer der Gründe für dieses ABI (zB in Speicherstapel Parameter über Register geben, anstatt zu speichern)

für ARM gibt es verschiedenes 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

ARM64 Konvention:

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

Für Linux auf PowerPC:

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

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

Und für Embedded gibt es die PPC EABI:

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

Dieses Dokument ist eine gute Übersicht über die verschiedenen Konventionen:

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

+0

Völlig neben dem Punkt. Das Poster der Frage würde nicht nach der 64-Bit-Syscall-Aufrufkonvention in Linux fragen, wenn es dasselbe wäre wie die allgemeinen ABI-Konvertierungen. –

+0

System V (Linux) ABIs befinden sich unter https://refspecs.linuxbase.org – kchoi

Verwandte Themen