2011-09-12 9 views
18

Ho appena iniziato a imparare l'assembly x64 e ho una domanda su funzioni, argomenti e stack. Per quanto ho capito, i primi quattro argomenti in una funzione vengono passati ai registri rcx, rdx, r8 e r9 (e xmm0-xmm3 per i float) in Windows. Quindi, una funzione aggiunta banale con quattro parametri sarebbe simile a questa:È necessario riservare lo spazio di stack per funzioni inferiori a quattro argomenti?

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

Tuttavia, ho incontrato documentation that mentions this:

Come minimo, ogni funzione deve prenotare 32 byte (quattro 64- valori bit) nello stack. Questo spazio consente ai registri passati nella funzione di essere facilmente copiati in una posizione di stack nota. La funzione callee non è necessaria per riversare i parametri del registro di input nello stack, ma la prenotazione dello spazio di stack assicura che sia possibile se necessario.

Quindi, devo prenotare lo spazio di stack anche se le funzioni che sto eseguendo richiedono quattro parametri o meno, o è solo una raccomandazione?

+1

http://www.agner.org/ optimize/optimizing_assembly.pdf capitolo 4 ha un esempio che sembra indicare che devi * sempre * riservare spazio. – user786653

+1

Dannazione, troppo tardi per la modifica. [oldnewthing] (http://blogs.msdn.com/b/oldnewthing/archive/2004/01/14/58579.aspx) post di blog sulla convenzione di chiamata amd64. – user786653

+0

Un altro pezzo del puzzle per te: hai una funzione *** ***, il che significa che non chiama altre funzioni. – jww

risposta

13

tua citazione è dalla parte "convenzione di chiamata" della documentazione. Per lo meno, non devi preoccuparti di questo se non chiami altre funzioni dal tuo codice assembly. Se lo fai, allora devi rispettare, tra le altre cose, le "zone rosse" e le considerazioni sull'allineamento dello stack, che la raccomandazione da te citata è intesa a garantire.

EDIT: this post chiarisce la differenza tra "zona rossa" e "spazio ombra".

+0

Ho visto la "zona rossa" usata nei documenti System V, ma i documenti di Windows usano "shadow space". Sono la stessa cosa? Se nessuno lo sa, chiederò in un'altra domanda. –

+0

Rispondendo parzialmente a me stesso: no, "zona rossa" e "spazio dell'ombra" non sono la stessa cosa. "Shadow space" è il nome dei 32 byte riservati nello stack. È riservato dal chiamante, quindi non è opzionale se vuoi che la tua funzione sia chiamabile con il solito ABI, ma non dovresti preoccuparti di ciò. –

+0

Quindi tutto quello che avrei dovuto fare per rendere tale codice di esempio sopra "corretta" è aggiungere 'sub RSP, 32' per l'inizio e 'aggiungere RSP, 32' fino alla fine, giusto? – Don

0

Ho appena incontrato questo non sapere e sembra essere il caso. Le prime due istruzioni in GetAsyncKeyState per esempio sovrascrivere lo stack di sopra del valore di ritorno nella zona di byte 0x20 che si dovrebbe riservare per il chiamato da utilizzare per i parametri:

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