Qual è lo scopo della zona rossa?


12

La zona rossa è un'area di dimensioni fisse in memoria oltre il puntatore dello stack che non è stato "allocato". I compilatori generano assembly per accedere a quell'area con semplici funzioni foglia.

Ma non vedo alcun reale vantaggio per la zona rossa. L'accesso alla memoria oltre il puntatore dello stack è davvero pericoloso e può facilmente portare alla corruzione dei dati . Perché anche farlo? Il salvataggio di 2 istruzioni del processore (push ebp; mov ebp esp) non darà una vera velocità.

Risposte:


16

La zona rossa è, puramente e semplicemente, un'ottimizzazione che può salvare le istruzioni. Significa che non è più necessario che il codice emesso sottragga ogni funzione dal puntatore dello stack per rendere la memoria locale in questo modo

sub XXX, %rsp 

all'inizio di ogni chiamata di funzione, anche se non sono funzioni foglia. Spesso il codice emesso dal compilatore può utilizzare lo spazio temporaneo nella zona rossa sotto il puntatore dello stack senza la necessità di salvarlo e prima di chiamare altre funzioni. Questa è un'ottimizzazione utile da avere a disposizione.

Se non è più necessario sottostare dal puntatore dello stack, il codice emesso può utilizzare rsp come puntatore di base, un lavoro normalmente riservato a rbp e il codice emesso può utilizzare rbp come altro registro per scopi generici.

Questo alla fine significa che il prologo e l'epilogo di ciascuna chiamata di funzione possono salvare due istruzioni che salverebbero e ripristinere rbp:

(assemblatore gnu)

pushq %rbp       # prologue [ two instructions not necessary ]
movq %rsp,%rbp

.... [code]

movq %rbp,%rsp   # epilogue [ two instructions not necessary ]
popq %rbp        

Nota che in gcc puoi passare il flag -mno-red-zone se non lo vuoi (ma l'ABI x86-64 lo richiede). Non è necessario che il kernel Linux sia conforme ABI e quindi tutto il codice del kernel è compilato con -mno-red-zone.

Inoltre, l'accesso alla memoria oltre il puntatore dello stack non è pericoloso se questa è la modalità operativa prevista. È solo pericoloso e può portare alla corruzione quando non è pianificato e inaspettato. Quando lo fa il codice emesso, sa cosa sta facendo.


Sì, lo capisco. Ma salvare 1 istruzione (sub da esp) è davvero ottimizzazione? Voglio dire, salvare pochi byte e 1 ciclo del processore per il prezzo della possibilità reale di corrompere i dati sembra strano. Forse ci sono altri motivi per farlo?
Alexander Dzyoba,

3
Non è proprio il sub di esp che è l'ottimizzazione, ma dal momento che non è più necessario eseguire il sub di esp, puoi usare esp come puntatore di base (normalmente fatto da ebp) e usare ebp per qualcos'altro nel codice funzione. Infine, poiché esp è ora il puntatore di base, il codice può evitare di salvare e ripristinare ebp nel prologo / epilogo. Chiarirò la risposta con queste informazioni extra
Brian Onn,

modifica e cambia in rbp / rsp invece di ebp / esp poiché la zona rossa è solo una parte dell'ABI x86-64 (anche se nulla impedisce a uno di usare la stessa tecnica con i registri a 32 bit; ma nessun compilatore lo fa oggi)
Brian Onn,

1
L'omissione del puntatore al frame non è affatto correlata alla zona rossa: il compilatore può indicizzare lo stack utilizzando %rspcome puntatore di base in entrambi i modi.
alecov,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.