2010-11-04 4 views
7

Ich lese "Computer Systems: A Programmer Perspective", erklärt Kapitel 3 mov Anweisung und Erklärung geben in einem Buch verwirrt mich.mov Anweisungen & Register - Verwirrung!

geben eine Funktion (Seite 142 1 Ausgabe)

int exchange(int *xp, int y) 
{ 
    int x = *xp; 
    *xp = y; 
    return x; 
} 

Assembly Code Körpers Funktion

movl 8(%ebp), %eax //Get xp 
movl 12(%ebp), %edx //Get y 
movl (%eax), %ecx //Get x at *xp 
movl %edx, (%eax) //Store y at *xp 
movl %ecx, %eax  //Set x as return value 

Was mich verwirrt, ist, was gespeichert werden soll, und wo
Hier wie ich das verstehe:

movl 8(%ebp), %eax //Get xp 

CPU bewegt sich +8 Bytes den Stack hinauf (vom Frame-Pointer %ebp), nimmt den an dieser Stelle gespeicherten Wert und speichert diesen Wert im Register %eax (zur Betonung - speichert den Wert, nicht die Adresse)

Ich habe Recht? Danke!

Antwort

9

Ja, es klingt wie Sie es richtig haben. IMHO, die AT & T 8(%ebp) Syntax ist weniger intuitiv als die Intel [ebp+8], die klarer ist. Die Klammern zeigen an, dass Sie den Wert an der Adresse in dem Register verwenden, und die Nummer ist der Offset von der Adresse, die Sie tatsächlich möchten.

+0

SEHR wahr ...... – ruslik

+1

Mit anderen Worten, weil '% ebp' den Zeiger speichert, verwenden wir Klammern um seinen Namen, um anzugeben, dass wir den gespeicherten Wert +8 Bytes von'% ebp' erhalten. In diesem Fall enthält '8 (% ebp)' den Zeiger '* xp'. Später, in der Zeile 'movl (% eax),% ecx', werden' xp' auf die gleiche Weise dereferenziert wie in der ersten Zeile des Assembler-Codes. – newprint

+0

Jetzt wird alles gestreckt. Parenthesis war die Quelle der Verwirrung! Vielen Dank ! – newprint

2

Ja, dies wird mit AT & T-Syntax, die von der Form:

instruction  source, dest 

Intel Montage ist the opposite order.

Sie haben auch Recht über die 8(%ebp) Bewegung von 8 Bytes aus dem Rahmenzeiger. Der Grund, warum es sich um 8 Bytes verschiebt, liegt insbesondere daran, dass Parameter in umgekehrter Reihenfolge auf den Stapel geschoben werden ("rechts" nach "links", wenn ein typischer Funktionsaufruf betrachtet wird). So wurde y zuerst gedrückt, dann xp und schließlich die Absenderadresse der Caller-Funktion (weshalb Sie 8 Bytes statt 4 verschieben).

1

Sie müssen verstehen, was ein Stapelrahmen ist. Erfahren Sie, was genau push und pop Anweisungen tun. Vor diesem Code gab es eine

push y_val 
    push xp_ptr 
    call exchange 
.cont  
... 
.exchange 
    push ebp 
    mov ebp, esp 
// .. rest of code 
// stack frame: 
    old_ebp_val ; [ebp] points here 
    .cont  ; [ebp + 4] 
    xp_ptr  ; [ebp + 8] 
    y_val 
+0

Meine Frage ist nicht über Stack, auch dachte Stack ist beteiligt. Es handelt sich um Werte, die in Register und Speicher abgelegt sind. – newprint

+1

@user Versuchen Sie RTTI zu implementieren. Behalte immer die Arten von Werten im Auge. – ruslik