Reputation: 4297
I am trying to understand assembly a little better, so I've been paying attention to the assembly output from CDB when I debug my code. My platform is an Intel Xeon with Windows 7.
The following C++ code:
int main()
{
int a = 30;
int b = 0;
b = ++a;
return 0;
}
produces the following assembly for the line with the increment operator:
b = ++a;
0x13f441023 <+0x0013> mov eax,dword ptr [rsp]
0x13f441026 <+0x0016> inc eax
0x13f441028 <+0x0018> mov dword ptr [rsp],eax //Move eax to some memory address
0x13f44102b <+0x001b> mov eax,dword ptr [rsp] //Move it back to eax?
0x13f44102e <+0x001e> mov dword ptr [rsp+4],eax
My question is, what is the purpose of moving the value in eax
to memory, then immediately moving the same value back into eax
, as indicated by the comments? Is this for thread safety, or just some artifact of a debug build?
Upvotes: 2
Views: 153
Reputation: 19706
The compiler initially translates your instructions into assembly using static single assignment values (SSA), meaning that each operation gets a temporary value to store its result. Only at a later backend stage, these values would be translated into machine registers according to your target machine, and possibly into memory locations if necessary (explicitly required or spilled due to lack of registers).
Between these stages, the optimizer may eliminate partial values, but initially ++a is one operation, and assigning a (post increment) into b is a second operation. Since a and b are both local variables, they will be stored on the stack (and must be visible there, in case you step with a debugger for example), a will reside in [rsp] and b in [rsp+4].
So your compiler, at some point, probably has (in some intermediate representation):
value1 = a
value2 = value1 + 1
a = value2 //self increment
b = a
Or something similar. a and b must be memory resident, but the operations will usually be done on registers, so at first the compiler does -
value1 = a
value2 = value1 + 1
0x13f441023 <+0x0013> mov eax,dword ptr [rsp]
0x13f441026 <+0x0016> inc eax
a = value2
0x13f441028 <+0x0018> mov dword ptr [rsp],eax
b = a
0x13f44102b <+0x001b> mov eax,dword ptr [rsp]
0x13f44102e <+0x001e> mov dword ptr [rsp+4],eax
Note that the intermediate values were kept in a register - in a normal compilation, they would have probably get eliminated altogether by one of the optimization passes (prior to register assignment and code generation).
Upvotes: 4
Reputation: 5321
just some artifact of a debug build?
Yes, just some artifact of a debug build (actually from an unoptimized build)
Upvotes: 0