我有一段C代码如下:
int main() {
char buf[4] = { 'A', 'B', 'C', 'D' };
buf[3] = 42;
return 0;
}
当我在Microsoft Visual Studio社区2015中编译它(调试模式,没有优化)并调试它时,我希望编译器在我的缓冲区上方和下方添加额外的8个字节的0xCC作为一个完整性检查,其中包含类似于在sub esp,Fh
之前rep stos
或类似内容。相反,我实际看到的是sub esp,0D0h
,它导致堆栈上的196个字节的0xCC高于为缓冲区分配的空间。我只是想知道为什么?对金丝雀来说似乎过分了。我已经包含了函数的完整反汇编以供参考:
push ebp
mov ebp,esp
sub esp,0D0h
push ebx
push esi
push edi
lea edi,[ebp-0D0h]
mov ecx,34h
mov eax,0CCCCCCCCh
rep stos dword ptr es:[edi]
mov byte ptr [buf],41h
mov byte ptr [ebp-0Bh],42h
mov byte ptr [ebp-0Ah],43h
mov byte ptr [ebp-9],44h
xor eax,eax
mov dword ptr [ebp-8],eax
mov eax,1
imul ecx,eax,3
mov byte ptr buf[ecx],2Ah
mov eax,0B100Dh
push edx
mov ecx,ebp
push eax
lea edx,ds:[0F916E0h]
call @_RTC_CheckStackVars@8 (0F91244h)
pop eax
pop edx
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Here是堆栈的屏幕截图(缩小了一点空间)。
我还尝试过只创建一个单字节的缓冲区,编译器为此分配0xCC字节。对于40字节缓冲区,它分配0xF0。我只想弄清楚这一点。为什么要分配这么多空间?
在Windows 10 64,Microsoft Visual Studio Community 2015版本14上以32位模式进行编译。