2011-09-12 13 views
18

Acabo de empezar a aprender el ensamblaje x64 y tengo una pregunta sobre las funciones, los argumentos y la pila. Por lo que yo entiendo, los primeros cuatro argumentos en una función pasan a registros rcx, rdx, r8 y r9 (y xmm0-xmm3 para flotantes) en Windows. Por lo que una función de suma trivial con cuatro parámetros se parecería a esto:¿Se está reservando el espacio de pila necesario para funciones de menos de cuatro argumentos?

add: 
    mov r10, rcx 
    add r10, rdx 
    add r10, r8 
    add r10, r9 
    mov rax, r10 
    ret 

Sin embargo, me he encontrado documentation that mentions this:

Como mínimo, cada función debe reservar 32 bytes (cuatro 64- valores de bit) en la pila. Este espacio permite que los registros pasados ​​en la función se copien fácilmente a una ubicación de pila bien conocida. La función de llamada no es necesaria para derramar los parámetros de registro de entrada a la pila, pero la reserva de espacio de pila asegura que puede hacerlo si es necesario.

Entonces, ¿tengo que reservar espacio en la pila incluso si las funciones que estoy realizando toman cuatro parámetros o menos, o es solo una recomendación?

+1

http://www.agner.org/ optimize/optimizing_assembly.pdf El capítulo 4 tiene un ejemplo que parece indicar que tiene que * siempre * reservar espacio. – user786653

+1

Maldita sea, demasiado tarde para editar. [newnewthingthing] (http://blogs.msdn.com/b/oldnewthing/archive/2004/01/14/58579.aspx) entrada de blog en la convención de llamadas AMD64. – user786653

+0

Otra pieza del rompecabezas para usted: tiene *** función de hoja ***, lo que significa que no llama a otras funciones. – jww

Respuesta

13

Su cita es de la parte de la "convención de llamadas" de la documentación. Como mínimo, no debe preocuparse por esto si no llama a otras funciones desde su código de ensamblado. Si lo hace, debe respetar, entre otras cosas, la "zona roja" y las consideraciones de alineación de la pila, que la recomendación que cita debe garantizar.

EDIT: this post aclara la diferencia entre "zona roja" y "espacio sombreado".

+0

He visto "zona roja" utilizada en los documentos del Sistema V, pero los documentos de Windows usan "espacio sombra". Son estos la misma cosa? Si nadie sabe, lo haré en otra pregunta. –

+0

Parcialmente respondiéndome a mí mismo: no, "zona roja" y "espacio sombreado" no son lo mismo. "Espacio sombreado" es el nombre de los 32 bytes reservados en la pila. Está reservado por la persona que llama, por lo que no es opcional si desea que su función sea invocable con el ABI habitual, pero no debería tener que preocuparse por ello. –

+0

Así que todo lo que tendría que hacer para que la muestra del código anterior sea "adecuada" es agregar 'sub rsp, 32' al comienzo y 'agregar rsp, 32' al final, ¿correcto? – Don

0

Me encontré con esto sin saber y parece ser el caso. Las dos primeras instrucciones en GetAsyncKeyState por ejemplo sobreescriben la pila por encima del valor de retorno en la zona de bytes 0x20 que se supone que reservar para el destinatario de la llamada a utilizar para los parámetros:

user32.GetAsyncKeyState - mov [rsp+08],rbx 
user32.GetAsyncKeyState+5- mov [rsp+10],rsi 
user32.GetAsyncKeyState+A- push rdi 
user32.GetAsyncKeyState+B- sub rsp,20 
Cuestiones relacionadas