2013-04-04 18 views
62

Questa domanda viene dalla risposta Stack Overflow domanda Why do books say, “the compiler allocates space for variables in memory”?, dove ho provato a dimostrare all'OP cosa succede quando si assegna una variabile nello stack e come il compilatore genera codice che conosce la dimensione della memoria da allocare. Apparentemente il compilatore alloca molto più spazio di quello necessario.Perché lo spazio in memoria è così grande?

Tuttavia, quando si compila il seguente

#include <iostream> 
using namespace std; 

int main() 
{ 
    int foo; 
    return 0; 
} 

Si ottiene il seguente output assembler con Visual C++ 2012 compilato in modalità debug senza ottimizzazioni on:

int main() 
{ 
00A31CC0 push  ebp 
00A31CC1 mov   ebp,esp 
00A31CC3 sub   esp,0CCh // Allocates 204 bytes here. 
00A31CC9 push  ebx 
00A31CCA push  esi 
00A31CCB push  edi 
00A31CCC lea   edi,[ebp-0CCh] 
00A31CD2 mov   ecx,33h 
00A31CD7 mov   eax,0CCCCCCCCh 
00A31CDC rep stos dword ptr es:[edi] 
    int foo; 
    return 0; 
00A31CDE xor   eax,eax 
} 

Aggiungendo un nuovo int al mio programma rende la riga commentata sopra alla seguente:

00B81CC3 sub   esp,0D8h // Allocate 216 bytes 

La domanda sollevata da @JamesKanze nella mia risposta collegata in cima, è il motivo per cui il compilatore, e apparentemente non è solo Visual C++ (non ho fatto l'esperimento con un altro compilatore), ha assegnato rispettivamente 204 e 216 byte, dove nella prima caso ne servono solo quattro e nel secondo ne ha solo otto?

Questo programma crea un eseguibile a 32 bit.

Dal punto di vista tecnico, perché potrebbe essere necessario allocare 204 byte anziché solo 4?

EDIT:

Calling due funzioni e la creazione di un double e due int nel principale, si ottiene

01374493 sub   esp,0E8h // 232 bytes 

Per lo stesso programma di modifica di cui sopra, lo fa in modalità di rilascio (nessuna ottimizzazione):

sub esp, 8    // Two ints 
movsd QWORD PTR [esp], xmm0 // I suspect this is where my `double` goes 
+10

Poiché è la modalità di debug. – ForEveR

+2

hai confrontato con un main leggermente più complesso chiamando alcune funzioni? so che g ++ assegna solo un ampio spazio da usare per gli argomenti delle funzioni. non so su visual C++ –

+9

La modalità di debug può contenere tutti i tipi di guardie di stack ecc. Come si comporta in modalità di rilascio? – Angew

risposta

101

Questo spazio aggiuntivo viene generato dall'opzione di compilazione/Zi. Che abilita Modifica + Continua. Lo spazio extra è disponibile per le variabili locali che potresti aggiungere quando modifichi il codice durante il debug.

Si vede anche l'effetto di/RTC, esso inizializza tutte le variabili locali su 0xcccccccc in modo che sia più facile diagnosticare i problemi a causa del dimenticare di inizializzare le variabili. Ovviamente nessuno di questo codice viene generato nelle impostazioni di configurazione di Release predefinite.

+7

Aha. Non ci avevo pensato. (So ​​che alcuni compilatori mettono uno spazio extra tra ogni funzione, proprio per questo motivo, ma non mi era mai venuto in mente che lo stesso fosse necessario per le variabili locali.) –

Problemi correlati