Assembler: “Function Call” assembler code produced by VC++
-
13-06-2021 - |
Question
I am by all means no assembler expert, and my knowledge on this topic is rather shallow, but I was curious on what the Microsoft VC++ Compiler does in a simple function call that does nothing else but returning a value.
Let us have the following function:
unsigned long __stdcall someFunction ( void * args) {
return 0;
}
Now, I know that with __stdcall
calling convention the CALLEE is responsible for stack unwinding, and with __cdecl
the CALLER of the function takes care of this. But for this example I would like to stick to the former.
With an non-optimized debug build I saw that the following output is being produced:
unsigned long __stdcall someFunction (void * args) {
00A31730 push ebp
00A31731 mov ebp,esp
00A31733 sub esp,0C0h
00A31739 push ebx
00A3173A push esi
00A3173B push edi
00A3173C lea edi,[ebp-0C0h]
00A31742 mov ecx,30h
00A31747 mov eax,0CCCCCCCCh
00A3174C rep stos dword ptr es:[edi]
return 0;
00A3174E xor eax,eax
}
00A31750 pop edi
00A31751 pop esi
00A31752 pop ebx
00A31753 mov esp,ebp
00A31755 pop ebp
00A31756 ret 4
I would thank anyone to explain this snippet of code for me if possible. I know that the xor
statement actually resets the eax
register to produce the zero return value. Also the ret 4
is self-explanatory to me. I think the edi
, esi
and ebx
registers are pushed before and popped after to save the original state, so that the function can use them freely maybe. But for the rest - I have no clue.
Any answer is very much appreciated! :)
Thanks!
Solution
So you're asking what these lines do:
00A3173C lea edi,[ebp-0C0h]
00A31742 mov ecx,30h
00A31747 mov eax,0CCCCCCCCh
00A3174C rep stos dword ptr es:[edi]
In Visual C++ debugging runtime library, uninitialized stack memory is initialized to contain 0xCC
bytes. This is what these instructions do.
At the beginning of the ASM code, there is the instruction sub esp,0C0h
that allocates 0xC0
bytes for the stack. However, there is no local variables used in this function, so where does this come from? It's for Edit+Continue support: you're able to add local variables and continue debugging.
The 0xCC
opcode means the INT 3
x86 assembly instruction, so if you try to execute that code (accidentally due to a bug), the program will throw an INT 3 exception which will be handled by the debugger or OS. So it's not just some random value.