当编译器从c ++代码创建完全相同类型的指令时,为什么不编译此代码

06n*_*amt 0 c++ assembly inline-assembly

请考虑以下代码

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;
}
Run Code Online (Sandbox Code Playgroud)

为什么这idiv ecx, ds:dword ptr[a] //causes compile error行当编译器idiv eax,dword ptr ds:[1308004h]从这行`int b = 2 生成这条指令时导致编译错误;

输出的错误是

error C2414: illegal number of operands
Run Code Online (Sandbox Code Playgroud)

有关装配输出,请参见下面的屏幕截图

装配输出

我正在使用Visual Studio 2013.任何解释都会受到重视

Mic*_*ael 5

看起来您的代码和反汇编可能是相同的,但这只是由于调试器选择显示反汇编的原因.

被除数IDIV是隐含的,并且总是EAX在除以32位值(实际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.
Run Code Online (Sandbox Code Playgroud)

因此,您尝试将另一个寄存器指定为股息将失败.

您只能指定除数IDIV,如:

cdq                 ; sign-extend eax into edx:eax
idiv dword ptr [a]  ; divide edx:eax by [a] 
Run Code Online (Sandbox Code Playgroud)