0

I have a basic function I made in C++:

int __cedcl add(int a, int b){
       return a + b;
}

For practice, I did my best at reversing it in IDA. Here is my result:

push    ebp             ; Store EBP Register
mov     ebp, esp        ; Adjust EBP to be Stack Pointer (Becomes reference to paramaters and such)
sub     esp, 0C0h       ; Allocate C0h Space on Stack
push    ebx             ; Save EBX register
push    esi             ; Save ESI Register
push    edi             ; Save EDI Register
lea     edi, [ebp+var_C0] ; Sets Location to Start Copying at Beginning of Allocated Space
mov     ecx, 30h        ; Stores #Repitions
mov     eax, 0CCCCCCCCh ; Value to store
rep stosd               ; Fill 30h space with CCCCCCCC
mov     eax, [ebp+arg_0] ; Store Argument 1 in EAX Return Register
add     eax, [ebp+arg_4] ; Add argument 2 to EAX Return Register
pop     edi             ; Restore EDI Register
pop     esi             ; Restore ESI Register
pop     ebx             ; Restore EBX Register
mov     esp, ebp        ; Restore Stack Pointer
pop     ebp             ; Restore Base Pointer
retn                    ; Return

However, where I am confused is why it is reserving 0x30 space on the stack when there aren't even local variables being used, as it simply leverages the EAX register since it can perform the necessary operations using the return register. Also, why does it by default store the value of registers that are unused within the function. ie. ebx, esi, and edx register?

I'd appreciate it if someone could clarify these questions or note any errors that I made when reversing the function if they spot them. Thanks!

tkausl
  • 13,686
  • 2
  • 33
  • 50
Drone6251
  • 128
  • 8
  • please copy the code here, [don't put it in images](https://meta.stackoverflow.com/q/303812/995714) – phuclv Oct 27 '17 at 02:29
  • Sorry, just fixed it. Seemed a little better formatted in IDA. – Drone6251 Oct 27 '17 at 02:36
  • 3
    thx 0xcccccccc is part of the runtime checks (using /RTC compiler option). All the extra bytes allocated on the stack and pushing _EBX_ when it isn't modified suggests you are probably not compiling with optimizations on. What happens if you turn them on? – Michael Petch Oct 27 '17 at 02:39
  • 3
    In case of MSVC then [0xCC will be filled to uninitialized areas](https://stackoverflow.com/q/370195/995714) to help debugging – phuclv Oct 27 '17 at 02:51
  • Ah gotcha. Thanks for your guys' help! – Drone6251 Oct 27 '17 at 02:53
  • If you'd like to take a look at the function without all this debugging stuff, make sure to declare it as [`__declspec(noinline)`](https://msdn.microsoft.com/en-us/library/kxybs02x.aspx) when compiling in release mode, otherwise it'll probably just vanish completely. – tkausl Oct 27 '17 at 03:46
  • I almost forgot: https://gcc.godbolt.org/ is a nice tool to examine generated assembly code in different compilers – tkausl Oct 27 '17 at 03:48
  • The general answer is, that the compiler is not supposed to output in some way minimal or optimal code for C source, but only "correct" (by C language definition, targetting C-abstract-machine) code. If it feels like reserving some unused space on stack, or doing few more useless calculations is a good idea, it will do it. With the optimization pass off it's simply the price for churning correct code out fast and in easy-to-debug form. With optimizations on the redundant things are often too subtle to even notice by human, but they still may happen if it's too much for optimizer to find better – Ped7g Oct 27 '17 at 08:45
  • One bug? in your comments: *"Fill 30h space with CCCCCCCC"* - it will store 0x30\*4 bytes, i.e. I would describe that rather as *"fill 0xC0 space with CC"*, or *"fill space with CCCCCCCC 0x30 times"* => can be deducted by reading, that 0xC0 bytes are affected. Your comment sounds like only 0x30 bytes are stored. – Ped7g Oct 27 '17 at 08:49
  • Sorry, meant to write 30h spaces. – Drone6251 Nov 02 '17 at 01:00

0 Answers0