VC9 refuses to cache global variables in a register, it seems:
Code:
for (int i = 0; i < 0xFFFFFFFF; i++)
00401821 xor esi,esi
{
MyGlobalVar++;
00401823 inc dword ptr [MyGlobalVar (404384h)]
if (i % 1000) cout << MyGlobalVar << endl;
00401829 mov eax,10624DD3h
0040182E imul esi
00401830 sar edx,6
00401833 mov eax,edx
00401835 shr eax,1Fh
00401838 add eax,edx
0040183A imul eax,eax,3E8h
00401840 mov ecx,esi
00401842 sub ecx,eax
00401844 je Help+47h (401867h)
00401846 mov edx,dword ptr [__imp_std::endl (402048h)]
0040184C mov eax,dword ptr [MyGlobalVar (404384h)]
00401851 mov ecx,dword ptr [__imp_std::cout (40204Ch)]
00401857 push edx
00401858 push eax
00401859 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402040h)]
0040185F mov ecx,eax
00401861 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402044h)]
00401867 inc esi
00401868 cmp esi,0FFFFFFFFh
0040186B jb Help+3 (401823h)
0040186D pop esi
}
If, on the other hand, it's a local var, it's cached in a register:
Code:
for (int i = 0; i < 0xFFFFFFFF; i++)
00401824 xor esi,esi
{
MyLocalVar++;
if (i % 1000) cout << MyLocalVar << endl;
00401826 mov eax,10624DD3h
0040182B imul esi
0040182D sar edx,6
00401830 mov eax,edx
00401832 shr eax,1Fh
00401835 add eax,edx
00401837 imul eax,eax,3E8h
0040183D mov ecx,esi
0040183F inc edi
00401840 sub ecx,eax
00401842 je Help+40h (401860h)
00401844 mov edx,dword ptr [__imp_std::endl (402048h)]
0040184A mov ecx,dword ptr [__imp_std::cout (40204Ch)]
00401850 push edx
00401851 push edi
00401852 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402040h)]
00401858 mov ecx,eax
0040185A call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402044h)]
00401860 inc esi
00401861 cmp esi,0FFFFFFFFh
00401864 jb Help+6 (401826h)
00401866 pop edi
00401867 pop esi
}
Following doesn't work, because even though the variable is volatile, it actually writes the value to a different address than the MyLocalVar, as its value doesn't change.
I'm not an expert at assembly, so if anyone wants to take a look at what's really happening, feel free. I'll post the assembly code too.
Code:
bool bExit = false;
void Thread1(const int& rMyLocalVar)
{
while (!bExit)
{
cout << rMyLocalVar << endl;
Sleep(100);
}
}
void Help()
{
volatile UINT MyLocalVar = 0;
CWinThread* pThread;
Stuff::NewThreadTF(&pThread, MyLocalVar, &Thread1);
for (int i = 0; i < 0xFFFFFFFF; i++)
{
MyLocalVar++;
//if (i % 1000) cout << MyLocalVar << endl;
}
bExit = true;
WaitForSingleObject(pThread->m_hThread, INFINITE);
}
Code:
00401950 sub esp,8
volatile UINT MyLocalVar = 0;
00401953 mov dword ptr [esp],0
CWinThread* pThread;
Stuff::NewThreadTF(&pThread, MyLocalVar, &Thread1);
0040195A mov eax,dword ptr [esp]
0040195D push edi
0040195E push eax
0040195F lea edi,[esp+0Ch]
00401963 call Stuff::NewThreadTF<unsigned int,void (__cdecl*)(int const &)> (401000h)
00401968 add esp,4
0040196B or eax,0FFFFFFFFh
0040196E mov ecx,1
00401973 pop edi
for (int i = 0; i < 0xFFFFFFFF; i++)
{
MyLocalVar++;
00401974 add dword ptr [esp],ecx
00401977 sub eax,ecx
00401979 jne Help+24h (401974h)
//if (i % 1000) cout << MyLocalVar << endl;
}
//Stuff::NewThreadTF(&pThread, NULL, &Thread2);
//Sleep(3000);
bExit = true;
0040197B mov byte ptr [bExit (404384h)],cl
WaitForSingleObject(pThread->m_hThread, INFINITE);
00401981 mov ecx,dword ptr [esp+4]
00401985 mov edx,dword ptr [ecx+2Ch]
00401988 push 0FFFFFFFFh
0040198A push edx
0040198B call dword ptr [__imp__WaitForSingleObject@8 (40202Ch)]