2010-11-24 12 views
9

Ich habe das ausgezeichnete Buch Programming Ground Up verfolgt, wollte Assembly lernen. Obwohl ich an dieser Stelle nicht im Buch war, wollte ich meine Assembly-Funktion von C. auf einer 32-Bit-Maschine aufrufen, das funktioniert so wie beim Arbeiten aus dem Buch.C zu Assembly Anrufkonvention 32bit vs 64bit

Was ich hier mache, speichert das erste Argument in %ebx und das zweite in %ecx.

.type power, @function 
.globl power 
power: 
    pushq %ebp 
    movl %esp, %ebp 
    subl $4, %esp 

    movl 8(%ebp), %ebx 
    movl 12(%ebp), %ecx 

ich diese (und den Rest der Funktion) in eine Objektdatei kompilieren, eine main.c erstellen, wo ich den Funktionsprototyp und es nennen, so etwas wie dieses:

int power(int b, int x); 
int a = power(2, 1); 

jedoch Wenn ich das auf einer 64-Bit-Maschine kompiliere, erhalte ich sehr unerwartete Ergebnisse. Ich habe das Offensichtliche modifiziert, wie die Tatsache, dass %esp und %epb durch %rsp und %rpb ersetzt werden müssen, aber das Graben mit GDB zeigt, dass die Argumente nirgendwo auf dem Stack zu finden sind!

Auschecken, was passiert, indem Sie die Option -S zu GCC verwenden, kann ich sehen, dass GCC die Argumente in den Registern speichert, anstatt die Variablen auf dem Stapel zu schieben.

movl $1, %esi 
movl $2, %edi 
call power 

Auf der 32-Bit-Maschine, tut es das, was ich erwarte, und drücken Sie die Argumente auf dem Stack:

movl $1, 4(%esp) 
movl $2, (%esp) 
call power 

Nun, was ist hier los? Warum übergibt GCC die Argumente in Registern auf 64 Bit und auf dem Stack auf 32 Bit? Das ist sehr verwirrend! Und ich kann nirgendwo eine Erwähnung finden. Gibt es jemanden, der mich über diese Situation aufklären kann?

+1

x64 Aufrufkonventionen unterscheiden sich von x86 Einsen. In den meisten Fällen werden aufgrund der zusätzlichen Register die ersten vier Argumente in Registern übergeben. – wj32

Antwort

27

64-Bit-C-Aufrufkonvention ist:% rdi,% rsi,% RDX,% rcx,% r8 und% r9

hier vollständige Beschreibung: "System V Application Binary Interface: AMD64 Architecture Processor Supplement" http://www.x86-64.org/documentation/abi.pdf

3,2 Funktion Aufrufsequenz

Als ich das gleiche Thema lernte, machte ich kleine C-Programme mit den erforderlichen Funktionen, kompilierte sie in 64-Bit-Compiler und lesen Sie den Assembler-Code von C-Compiler erzeugt. Der C/C++ - Compiler kann als eine Art Assembly-Referenz verwendet werden.

+0

Ich habe das genaue Dokument überflogen, aber ich habe es jetzt genauer studiert, und es ist alles da, und es macht jetzt völlig Sinn. Vielen Dank! – Cbsch

+0

Wie für Ihre Bearbeitung: Ja, so versuche ich es auch. Das Ändern der Assembly-Funktion war kein Problem, und zu beobachten, was der Compiler macht, ist auch kein Problem, das Problem war, dass ich die Regeln für dieses Verhalten nicht verstanden habe. Aber das Dokument, mit dem Sie verlinkt haben, war die perfekte Antwort dafür. – Cbsch

+10

Als eine Anmerkung verwendet Windows eine andere ABI - http://msdn.microsoft.com/en-us/library/ms235286.aspx mit nur RCX, RDX, R8, R9 für Argumente. – Brian

Verwandte Themen