考虑以下代码
int a = 10;
int b = 2;
int c = 0;
int asmdivide(void);
int main(int argc, char* argv[])
{
c = a / b;
asmdivide();
return 0;
}
int asmdivide()
{
__asm
{
push dword ptr[a]
push dword ptr[b]
pop ecx
idiv ecx, dword ptr[a] //causes compile error
push ecx
pop dword ptr[c]
}
return c;
}
为什么这一行idiv ecx, ds:dword ptr[a] //causes compile error
当编译器从这一行生成这条指令idiv eax,dword ptr ds:[1308004h]
时会导致编译错误`int b = 2;
输出的错误是
error C2414: illegal number of operands
请参阅下面的屏幕截图,了解装配输出
我正在使用Visual Studio 2013。 任何解释都会被重视
答案 0 :(得分:5)
看起来您的代码和反汇编可能是相同的,但这仅仅是调试器选择显示反汇编的原因。
IDIV
的红利是隐含的,在除以32位值(实际为EAX
)时始终为EDX:EAX
。引用英特尔手册:
F7 /7 IDIV r/m32 M Valid Valid Signed divide EDX:EAX by r/m32, with result
stored in EAX ←Quotient, EDX ←Remainder.
因此,您尝试将另一个寄存器指定为被除数将失败。
您只能为IDIV
指定除数,如:
cdq ; sign-extend eax into edx:eax
idiv dword ptr [a] ; divide edx:eax by [a]