2012-11-13 3 views
5

私はASMの概念に慣れようとしていますが、MSVCによって生成された逆アセンブリを観察しながら、私は完全に理解できないことがあります。ここに私のテストケースである:すべてのレジスタを使用した後のmsvcコンパイラの動作

のようなものを生成
#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; 
} 

:だから、私の質問がある

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 
    (...) 

を: コンパイラは "< < < < < <" でマークされた行で何をするのか?私の は、レジスタ値 を格納するための変数を作成したことを推測します。ebpを使用しているのでスタックにあるようですが、 は「グローバル変数」のようなものか、 スコープ(フレーム)のみ?

ありがとうございます。

+2

あなたは* register spilling *を調べるべきです、これはほとんどのコンパイラがフリーレジスタを使い果たすことを処理する方法です(最適化レベル、生成されるコード、SSAが使用されている場合など)。 – Necrolis

+0

「レジスタ溢れる」という言葉が必要な言葉だったようです。ありがとう。 – benji

答えて

4

MSVCは、ブロックスコープの変数を保持しているレジスタにこぼれたときにスタックに、またはレジスタがグローバルを保持しているときに固定のオフセットに、適切なメモリにレジスタを書き出します。どの時点でも、コンパイラはどの変数がどのレジスタにあるかを知っています。

グローバル変数にローカル変数を流すことはできません。スレッドとリエントラントのために、予期しない数のローカル変数が存在する可能性があるからです。コンパイラはグローバル変数をスタックスロットに一時的に流すことができるかもしれませんが、これはスレッドの存在下では非常に複雑です。

+0

ああ、それは今や理にかなっています。どうもありがとう。 – benji

関連する問題