Beh*_*ooz 3 c++ 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
}
}
Run Code Online (Sandbox Code Playgroud)
MS C++ Automagicaly将这些代码(标有**)添加到我的程序中.
为什么?
怎么避免呢?
**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
Run Code Online (Sandbox Code Playgroud)
Han*_*ant 20
它是标准函数入口和出口代码.它建立并拆除堆栈框架.如果你不想要它,可以使用__declspec(裸).如果你这样做,别忘了包括RET.
但是,您的代码片段依赖于有效的堆栈帧,您的"m"变量需要它.它在[ebp-10]处理.如果没有前导码,ebp寄存器将无法正确设置,您将破坏调用者的堆栈帧.
它正在维护调用堆栈.如果您将该函数定义为
int NativeLoop() { }
Run Code Online (Sandbox Code Playgroud)
你会看到相同的组件.
我记得你可以__declspec(naked)在MSVC++中,这意味着你必须自己处理堆栈,这意味着你必须保存你破坏的每个寄存器,并恢复它.
没有一个规则可以正确地做到这一点,因为它取决于调用约定.请参见http://en.wikipedia.org/wiki/X86_calling_conventions.
旁注:在gcc中,你明确地向编译器说明你将驱动无效的内容,以便gcc将输出更优化的保存/恢复/堆栈帧代码(如果有的话).在MSVC中,asm主要是编译器的黑盒子,它通常/总是最差的.
请参阅http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#ss5.3,gcc内联asm语法更难看,但实际上更有效.
| 归档时间: |
|
| 查看次数: |
556 次 |
| 最近记录: |