当前位置: 动力学知识库 > 问答 > 编程问答 >

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

问题描述:

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

网友答案:

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.

网友答案:

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

int NativeLoop() { }

You would see the same assembly.

网友答案:

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.

网友答案:
  **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
网友答案:

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

分享给朋友:
您可能感兴趣的文章:
随机阅读: