Tutorial :why does MS C++ add this code to assembly?



Question:

i have some code(inline assembly).

void NativeLoop()  {      int m;      __asm      {          PUSH ECX          PUSH EDX          MOV  ECX, 100000000  NEXTLOOP:          MOV  EDX, ECX          AND  EDX, 0X7FFFFFFF          MOV  DWORD PTR m, EDX          DEC  ECX          JNZ  NEXTLOOP          POP  EDX          POP  ECX      }  }  

MS C++ Automagicaly adds these codes(marked with **) to my procedure.
Why?
how to avoid it?

  **push        ebp      **mov         ebp,esp     **push        ecx      push        ecx      push        edx      mov         ecx,5F5E100h   NEXTLOOP:    mov         edx,ecx     and         edx,7FFFFFFFh     mov         dword ptr m,edx     dec         ecx      jnz         NEXTLOOP    pop         edx      pop         ecx      **mov         esp,ebp     **pop         ebp      **ret  


Solution:1

It is the standard function entry and exit code. It establishes and tears down the stack frame. If you don't want it you can use __declspec(naked). Don't forget to include the RET if you do.

However, your snippet relies on a valid stack frame, your "m" variable requires it. It is addressed at [ebp-10]. Without the preamble, the ebp register won't be set correctly and you'll corrupt the stack frame of the caller.


Solution:2

It's maintaining the call stack. If you defined the function as

int NativeLoop() { }  

You would see the same assembly.


Solution:3

I remember that you can __declspec(naked) in MSVC++, meaning that you have to take care of the stack yourself, that means you must save every register you clobber, and restore it.

There is no the-one-rule to do that properly, as it depends on calling convention. See http://en.wikipedia.org/wiki/X86_calling_conventions .

Sidenote: In gcc, you explitly state to the compiler what you will drive invalid, so that gcc will output more optimal save/restore/stackframe-code, if any. In MSVC, asm is mostly a blackbox to the compiler, for which it will often/always the worst.

See http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#ss5.3 , gcc inline asm syntax is more ugly, but effectively more effective.


Solution:4

  **push        ebp  ;save EBP register    **mov         ebp,esp  ;Save the stackframe    **push        ecx  ; So that the variable `m` has an address  ;...    **mov         esp,ebp ;restore the stack frame to it's original address    **pop         ebp   ;restore EBP register    **ret ;return from function call  


Solution:5

If you can do a search on C++ calling conventions, you'll understand better what the compiler is doing.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »