La "zona rossa" non è strettamente necessaria. Secondo i tuoi termini, potrebbe essere considerato "inutile". Tutto ciò che si può fare usando la zona rossa, si potrebbe anche fare il modo tradizionale in cui lo si faceva mirando all'ABI IA-32.
Ecco ciò che il AMD64 ABI dice circa la "zona rossa":
L'area di 128 byte al di là della posizione puntata da %rsp
è considerata riservata e non può essere modificato da un segnale o interrompere gestori. Pertanto, le funzioni possono utilizzare quest'area per i dati temporanei che non sono necessari per le chiamate di funzione. In particolare, le funzioni foglia possono usare quest'area per l'intero frame dello stack, piuttosto che regolare il puntatore dello stack nel prologo e nell'epilogo. Questa zona è conosciuta come la zona rossa.

Il vero scopo della zona rossa è come un ottimizzazione. La sua esistenza consente al codice di presumere che i 128 byte inferiori a rsp
non vengano violati in modo asincrono dai segnali o dai gestori di interrupt, il che rende possibile utilizzarlo come spazio di lavoro. Ciò rende superfluo creare in modo esplicito lo spazio libero nello stack spostando il puntatore dello stack in rsp
. Questa è un'ottimizzazione perché ora è possibile eliminare le istruzioni per decrementare e ripristinare rsp
, risparmiando tempo e spazio.
Quindi sì, mentre si potrebbe fare questo con AMD64 (e avrebbe bisogno di farlo con IA-32):
function:
push rbp ; standard "prologue" to save the
mov rbp, rsp ; original value of rsp
sub rsp, 32 ; reserve scratch area on stack
mov QWORD PTR [rsp], rcx ; copy rcx into our scratch area
mov QWORD PTR [rsp+8], rdx ; copy rdx into our scratch area
; ...do something that clobbers rcx and rdx...
mov rcx, [rsp] ; retrieve original value of rcx from our scratch area
mov rdx, [rsp+8] ; retrieve original value of rdx from our scratch area
add rsp, 32 ; give back the stack space we used as scratch area
pop rbp ; standard "epilogue" to restore rsp
ret
Non necessità di farlo nei casi in cui si serve solo un'area scratch da 128 byte (o più piccola), perché allora possiamo usare la zona rossa come area di scratch.
Inoltre, dal momento che non abbiamo più per diminuire lo stack pointer, possiamo usare rsp
come il puntatore base (invece di rbp
), rendendo inutile per salvare e ripristinare rbp
(nel prologo ed epilogo), e anche liberando su rbp
da utilizzare come un altro registro generale!
(Tecnicamente, accendendo frame-pointer omissione (, abilitato di default con -O1
poiché l'ABI consente) sarebbe anche rendere possibile per il compilatore elidere prologo e sezioni epilogo, con gli stessi vantaggi. Tuttavia, in assenza di una zona rossa, la necessità di regolare il puntatore dello stack per riservare lo spazio non cambierà.)
Nota, tuttavia, l'ABI garantisce solo che le cose asincrone come i segnali e i gestori di interrupt non modificano la zona rossa. Le chiamate ad altre funzioni possono sovraccaricare i valori nella zona rossa, quindi non è particolarmente utile se non nelle funzioni foglia (che sono quelle funzioni che non chiamano altre funzioni, come se fossero nella "foglia" di un albero di chiamata di funzioni) .
Un ultimo punto: il Windows x64 ABIdeviates slightly from the AMD64 ABI used on other operating systems. In particolare, non ha alcun concetto di "zona rossa". L'area oltre rsp
è considerata volatile e può essere sovrascritta in qualsiasi momento. Al contrario, richiede che il chiamante assegni uno stack home address space, che è quindi disponibile per l'utilizzo del callee nel caso in cui debba rovesciare uno dei parametri passati dal registro.
Il secondo snippet di codice che hai mostrato qui è sbagliato. Se decrementi il puntatore dello stack, devi * ripristinarlo prima di tornare dalla funzione. Quindi, dovresti aggiungere 'add rsp, 1024' prima di' ret'. –
Quale ABI è quello? Presumo quello Linux, ma ce ne sono altri, ad es. quello per Windows 64, Mac OS X 64 bit, ecc. –
@rudy Per quanto ne so, ci sono solo due ABI x86-64: il System V AMD64 ABI (usato da Linux, Solaris, OS X e altri POSIX -compliant operating systems) e l'implementazione di Microsoft utilizzata su Windows. La domanda sembra riguardare la prima. –