2012-11-13 11 views
5

Ich versuche, in ASM-Konzepte zu gelangen, und während ich die durch MSVC erzeugte Disassemblierung beobachte, gibt es etwas, das ich nicht vollständig verstehen kann. Hier ist mein Testfall:MSVC-Compiler-Verhalten, nachdem alle Register verwendet werden

#include <tchar.h> 
#include <conio.h> 
#include <iostream> 
using namespace std; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int v1 = 1; 
    int v2 = 2; 
    int v3 = 3; 
    int v4 = 4; 
    int v5 = 5; 
    int v6 = 6; 
    int v7 = 7; 
    int v8 = 8; 
    int v9 = 9; 
    int v10 = 10; 
    int v11 = 11; 
    int v12 = 12; 
    int v13 = 13; 
    int v14 = 14; 
    int v15 = 15; 
    int v16 = 16; 

    int sum = v1+v2 * (v3+v4 * (v5+v6 * (v7+v8 * (v9+v10 * (v11+v12 * (v13+v14 * (v15+v16))))))); 

    _getch(); 
    return 0; 
} 

, die wie etwas erzeugt:

mov eax, v1 
    mov edx, v3 
    mov ecx, v5 
    mov ebx, v7 
    mov esi, v9 
    mov edi, v11 // all 6 available registers are filled 
    mov dword ptr [ebp-60h), eax // free eax <<<<<< 
    mov eax, v15 // fill it again 
    add eax, v16 
    imul eax, v12 
    (...) 

Also, meine Frage ist: Was den Compiler zu tun hat an der Linie, die mit "< < < < < <" ? Meine Vermutung ist, dass es eine Variable zum Speichern der Register-Wert in erstellt hat. Sieht aus wie es auf dem Stapel ist, wie es die ebp verwendet, aber ist es etwas wie eine "globale Variable", oder ist es eine Variable in der aktuellen nur Rahmen (Rahmen)?

Vielen Dank im Voraus.

+2

sollten Sie in * register spilling * suchen, so behandeln die meisten Compiler die freien Register (es gibt viele Fälle, je nach Optimierungslevel, der zu generierende Code, wenn SSA verwendet wird usw.). – Necrolis

+0

Sieht aus wie "Register verschütten" war der Begriff, den ich brauchte. Vielen Dank. – benji

Antwort

4

MSVC wird Register an den entsprechenden Speicher verschütten: an den Stack, wenn es ein Register übergibt, das eine Variable mit Blockbereich enthielt, oder an einen festen Offset, wenn das Register global war. Zu jedem Zeitpunkt weiß der Compiler, welche Variablen sich in welchem ​​Register befinden.

Sie können lokale Variablen nicht in den globalen Speicher streuen, da es aufgrund von Threads und Reentrancy möglicherweise eine unvorhersehbare Anzahl von ihnen gibt. Ein Compiler kann möglicherweise vorübergehend eine globale Variable in einen Stack-Slot übertragen, was jedoch bei Threads sehr komplex ist.

+0

Ah, das macht jetzt Sinn. Danke vielmals. – benji