考虑以下代码
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]//导致编译错误
当编译器生成这条指令时导致编译错误 idiv eax,dword ptr ds:[ 1308004h]
从这一行`int b = 2;
输出的错误是
error C2414: illegal number of operands
汇编输出请看下面的截图
我正在使用 Visual Studio 2013。 任何解释都将受到重视
最佳答案
看起来您的代码和反汇编是一样的,但这只是由于调试器选择如何显示反汇编。
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]
关于c++ - 为什么当编译器从 C++ 代码创建完全相同类型的指令时,此代码无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25872084/