2015-04-23 12 views
7

Czytam mój podręcznik i ma kod dla funkcji zamiany:Pointer Deferencing w x86 Kod Zgromadzenie

w C:

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

W x86 Zgromadzenia z adnotacjami:

// xp is at %ebp + 8, y at %ebp + 12 
movl 8(%ebp), %edx  // get xp 
movl (%edx), %eax  // get x at xp 
movl 12(%ebp), %ecx  // get y 
movl %ecx, (%edx)  // store y at xp 

Tak więc od mojego zrozumienia, jeśli int * xp wskazał na I na adres A, to pierwsza linia kodu złożenia przechowuje A na% edx. Następnie dostaje dereferencji w drugiej linii i przechowywane w% eax.

Jeśli to prawda, zastanawiam się, dlaczego "8 (% ebp) wiersza 1" nie dereferencji wskaźnika, przechowywanie int I w% edx zamiast adresu A? Czy to nie nawiasy w montażu?

Czy to oznacza, że ​​gdy wskaźniki są naciskane na stos, adres wskaźnika jest wciskany zamiast wartości, którą ma, więc 8 (% ebp) technicznie posiada & PD?

Chciałam tylko wyjaśnić, czy moje zrozumienie było prawidłowe.

+2

Ebp to adres ramki stosu, w której znajdują się wszystkie argumenty. Ebp + 8 to adres wartości xp (czyli adres int). Technicznie, tak - ebp + 8 == & xp. – user3125367

+0

* oznacza to, że gdy wskaźniki są wypychane na stos, adres wskaźnika jest wciskany zamiast wartości, którą trzyma * - I nie, wartość wskaźnika jest przesuwana na stos. – user3125367

Odpowiedz

5

xp to wskaźnik. Ma czterobajtową wartość. Ta wartość jest przekazywana na stos przez funkcję wywołującą. Prolog funkcji, który nie został wyświetlony, ustawia wskaźnik bazowy w ebp. Wartość xp jest przechowywana w przesunięciu 8 względem tego wskaźnika bazowego.

Więc pierwsza linia kodu dereferences wskaźnik bazowy, jak wskazano w nawiasach, z przesunięciem od 8 do pobierania wartości z xp (co jest adres, który wskazuje na int) i umieszcza je w edx.

Drugi wiersz kodu używa adresu w edx w celu pobrania wartości int i umieszczenia tej wartości w eax. Zwróć uwagę, że zwracana wartość funkcji będzie wartością z eax.

Trzecia linia odznacza wskaźnik bazowy z przesunięciem 12, aby uzyskać wartość y.

Czwarta linia używa adresu w edx, aby umieścić y w miejscu, które wskazuje xp.

2

%bp to wskaźnik bazowy stosu, który musi być odsyłany przed uzyskaniem dostępu do dowolnego elementu stosu. Tak więc movl 8 (% bp),% edx` pobiera wartość, która znajduje się na przesunięciu 8 w bieżącej ramce stosu.

Ta wartość jest wskaźnikiem, więc musimy usunąć ją w celu uzyskania dostępu do jej zawartości, bez względu na to, czy chodzi o czytanie czy pisanie.

OTOH, y to int, więc aby go uzyskać wystarczy tylko movl 12(%ebp), %ecx i nie trzeba już wykonywać żadnych dodatkowych czynności.

Tak więc movl %ecx, (%edx) jest dokładnie tym, co należy: ustaw wartość zapisaną w ecx w pamięci wskazanej przez edx.