c pointers assembly x86 att

Pointer Deferencing en el código de ensamblaje x86



pointers assembly (2)

Estoy leyendo mi libro de texto y tiene el código para una función de intercambio:

Cª:

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

En x86 Asamblea con anotaciones:

// 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

Entonces, desde mi entendimiento, si el int * xp apuntaba a una int I en la dirección A, entonces la primera línea del código ensamblador almacena A en% edx. Luego se desreferencia en la segunda línea y se almacena en% eax.

Si esto es cierto, me pregunto por qué la línea 1 "8 (% ebp)" no desreferencia el puntero, almacenando el int I en% edx en lugar de la dirección A? ¿No es eso lo que hacen los paréntesis en la asamblea?

¿O eso significa que cuando los punteros se insertan en la pila, la dirección del puntero se empuja en lugar del valor que tiene, por lo que 8 (% ebp) técnicamente tiene & xp?

Solo quería aclarar si mi comprensión era correcta.


%bp es el puntero de la base de la pila que se debe referenciar antes de que pueda acceder a cualquier elemento de la pila. Así que movl 8 (% bp),% edx` recupera el valor que se encuentra en el desplazamiento 8 en el marco de la pila actual.

Este valor es un puntero, por lo que debemos desreferenciarlo para acceder a sus contenidos, ya sea para lectura o escritura.

OTOH, y es un int, por lo que obtenerlo es solo movl 12(%ebp), %ecx y no se requiere más actoin.

Así que movl %ecx, (%edx) es exactamente lo correcto: ponga el valor que está almacenado en ecx en la memoria apuntada por edx .


xp es un puntero. Tiene un valor de cuatro bytes. Ese valor es empujado a la pila por la función de llamada. El prólogo de funciones, que no ha mostrado, configura un puntero base en ebp . El valor de xp se almacena en el desplazamiento 8 con respecto a ese puntero base.

De modo que la primera línea de código desreferencia el puntero base, como lo indican los paréntesis, con un desplazamiento de 8 para recuperar el valor de xp (que es una dirección que apunta a un int) y lo coloca en edx .

La segunda línea de código usa la dirección en edx para recuperar el valor de int , y pone ese valor en eax . Tenga en cuenta que el valor de retorno de la función será el valor en eax .

La tercera línea desreferencia el puntero base, con un desplazamiento de 12, para obtener el valor de y .

La cuarta línea usa la dirección en edx para colocar y en la ubicación a la que apunta xp .