Just a couple of curiosity questions on this very simple function that adds two numbers together. Here is the anotated disassembly (questions are in code marked with ???)
Here is the C function
int Add(int x , int y)
{
int additionAnswer = 0 ;
additionAnswer = x + y;
return additionAnswer;
}
Here is the disassembly (DEBUG BUILD) with my anotations and questions
int Add(int x , int y)
{
push ebp ; preserve base pointer
mov ebp,esp ; move base pointer to start of stack frame for this function
sub esp,0CCh ; ??? is this preserving space on the stack for local
; variable..204bytes seems execessive!!!
push ebx //??? Why is this preserving ebx, esi and edi
push esi //??? when clearly this function does not use it!
push edi
lea edi,[ebp-0CCh] ; ??? Why is it loading the address of top of stack into edi?
mov ecx,33h ; ??? What is that doing
mov eax,0CCCCCCCCh ; ??? What is that doing
rep stos dword ptr es:[edi] ; ??? What is that doing
mov dword ptr [additionAnswer],0 ;int additionAnswer = 0
mov eax,dword ptr [x] ;eax = x
add eax,dword ptr [y] ;eax = eax + y
mov dword ptr [additionAnswer],eax ;answer = eax
mov eax,dword ptr [additionAnswer] ; return addition in eax
pop edi ;restore edi even though I didn't use it !!!!
pop esi ;restore esi even though I didn't use it !!!!
pop ebx ;restore ebx even though I didn't use it !!!!
mov esp,ebp ; clean up stack frame and restore sp to
;4 bytes above it's original pre-frame value
pop ebp ;restore base pointer back to it's original value
;and at same time this will add 4 to sp hence restoring it
;back to its former pre-frame value, and pointing to return address on stack
ret
I dug around a bit and apparently in Win32, the following must be preserved: edi, esi, ebp and ebx. I can understand source/destination index registers (esi /edi) might be used by the calling function , but why doesn't the calling function preserve EBX itself rather than my function doing the unnecessary donkey work, surely the caller knows what it needs to preserve and what it does not! Finally why preserve EBX and not say ECX, again why is it the responsibility of my function to preserve these registers (or even any register at all!).
one last thing I don't see any of these register preservation code when building in release mode (without optimizations)......is this a debug only concept????