使用所有寄存器后的msvc编译器行为

时间:2012-11-13 11:31:03

标签: c++ visual-c++ cpu-registers

我正在尝试进入ASM概念,并且在观察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
    (...)

所以,我的问题是:     编译器在标有“&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;”的行上做了什么?我的     猜测是它创建了一个存储寄存器值的变量     因为它使用ebp看起来是在堆栈上,但是它是     像“全局变量”之类的东西,或者它是当前的变量     范围(框架)?

提前致谢。

1 个答案:

答案 0 :(得分:4)

MSVC会将寄存器溢出到适当的内存:当堆栈溢出一个包含块范围的变量的寄存器时,或者当寄存器保持全局时,将寄存器溢出到固定的偏移量。在任何时候,编译器都知道哪个变量在哪个寄存器中。

您不能将局部变量溢出到全局内存,因为线程和重入可能导致它们的数量不可预测。编译器可以暂时将全局变量溢出到堆栈槽,但是在存在线程时这非常复杂。