2010-11-04 15 views
7

Czytam "Systemy komputerowe: Perspektywa programisty", rozdział 3 wyjaśnia instrukcję mov, a wyjaśnienie w książce wprowadza mnie w zakłopotanie.instrukcje i rejestry mov - zamieszanie!

dać funkcję (strona 142 wydanie 1'S) Kod

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

Zgromadzenie ciało funkcji za

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 

Co mnie myli, jest to, co ma być przechowywany, a gdzie
Oto jak to rozumiem:

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

Przenoszenie procesora +8 bajtów górę stosu (od wskaźnika ramki %ebp), przyjmuje wartość przechowywaną w tym miejscu i zapisuje tę wartość w rejestrze %eax (do naciskiem - przechowuje wartość, a nie adres)

mam rację? Dzięki!

Odpowiedz

9

Tak, to brzmi jak masz rację. Składnia IMHO, AT & T jest mniej intuicyjna niż Intel [ebp+8], co jest bardziej przejrzyste. Nawiasy pokazują, że używasz wartości pod adresem w rejestrze, a liczba jest przesunięciem względem tego adresu, który faktycznie chcesz.

+0

BARDZO prawdziwy ...... – ruslik

+1

Innymi słowy, ponieważ '% ebp' przechowuje wskaźnik, używamy nawiasów wokół jego nazwy, aby określić, że otrzymujemy zapisaną wartość + 8 bajtów od'% ebp'. W tym przypadku '8 (% ebp)' zawiera wskaźnik '* xp'. Później, w linii 'movl (% eax),% ecx', wyłuskujemy' xp' w taki sam sposób jak w pierwszym wierszu kodu montażowego – newprint

+0

Teraz wszystko jest wyprostowane. Nawias był źródłem nawiasów! Dzięki ! – newprint

2

Tak, to jest przy użyciu AT & T składni, która ma postać:

instruction  source, dest 

montaż Intel the opposite order.

Masz również rację co do tego, że 8(%ebp) przesuwa się o 8 bajtów od wskaźnika ramki. Powodem, dla którego porusza się 8 bajtów, jest to, że parametry są popychane na stos w odwrotnej kolejności ("prawo" do "lewej", gdy patrzymy na typowe wywołanie funkcji). W związku z tym y został najpierw wciśnięty, a następnie xp, a na koniec adres zwrotny funkcji wywołującej (dlatego przenosimy 8 bajtów zamiast 4).

1

Musisz zrozumieć, co to jest ramka stosu. Dowiedz się, co dokładnie robią instrukcje push i pop. Przed tym kodzie nie było

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

Moje pytanie nie dotyczy stosu, nawet stos myśli jest zaangażowany. Chodzi o wartości zapisane w rejestrze i pamięci. – newprint

+1

@user Spróbuj zaimplementować RTTI. Zawsze śledź rodzaje wartości. – ruslik