我想知道MSVC 2010如何为易失性局部变量生成代码并进行了测试。这个简单的测试函数使用volatile变量:
int proc1(int a, int b) {
int volatile volvar=0;
int c=a;
if (b>a)
c=0;
return c;
}
由于volvar
关键字,优化器不应该消除整数volatile
的初始化。生成的64位程序集意外地看起来像这样:
_TEXT SEGMENT
volvar$ = 8
a$ = 8
b$ = 16
?proc1@@YAHHH@Z PROC ; proc1, COMDAT
; 3 : int volatile volvar=0;
xor eax, eax
; 4 :
; 5 : int c=a;
; 6 : if (b>a)
cmp edx, ecx
cmovg ecx, eax
mov DWORD PTR volvar$[rsp], eax;<---what is 'mov DWORD PTR [8+rsp], eax'?
; 7 : c=0;
; 8 : return c;
mov eax, ecx
; 9 : }
ret 0
?proc1@@YAHHH@Z ENDP ; proc1
_TEXT ENDS
END
注意符号volvar$
等于8,因此为易失性局部变量赋值生成的指令写入地址[8 + rsp]。 RSP没有被修改,所以应该指向返回地址。但我对64位堆栈布局的理解是,返回地址之上不再有任何参数。相反,[8 + rsp]应该指向CALLING FUNCTION的RCX存储位置,它与我们当前的功能无关。这会不正确地覆盖调用函数的堆栈吗?
这是编译器的错误还是我对64位堆栈帧布局的误解?