Assembly fidiv:除以寄存器时操作数类型错误

Assembly fidiv:除以寄存器时操作数类型错误,assembly,x86,fpu,Assembly,X86,Fpu,以下面的代码为例: void calculate(int int_number) { __asm { fld1 mov eax, 5 fidiv eax ; A } } 如果我试图编译它,A行将失败,出现错误C2415:操作数类型不正确。如果我用整数常量替换eax,同样的问题也会发生。但是,如果我将int_number作为fidiv参数传递: void calculate(int int_number) { __as

以下面的代码为例:

void calculate(int int_number) {
    __asm {
        fld1
        mov eax, 5
        fidiv eax    ; A
    }
}
如果我试图编译它,A行将失败,出现
错误C2415:操作数类型不正确
。如果我用整数常量替换
eax
,同样的问题也会发生。但是,如果我将
int_number
作为
fidiv
参数传递:

void calculate(int int_number) {
    __asm {
        fld1
        fidiv int_number
    }
}
代码编译正确

那么除以寄存器有什么不对呢


我在Windows 8.1 64位上使用Visual Studio。

尽管答案已经是注释:操作数必须是内存操作数

看看手册,上面写着:

DA/6 FIDIV m32int
DE/6 FIDIV m16int

如果您也可以为该操作数选择一个寄存器,它不会列出FIDIV r/m32int。某些FPU指令组(基于其第一个字节的组)被拆分为两个子组,其中包含不同的指令(所有组都被拆分,但某些组(如
D8
)被拆分为两个子组,仅因其操作数不同而不同)。
DA
DE
组是分成两个完全不同的子组的示例。这些组根据ModR/M字节中的“mod”字段进行拆分,00到10是一个组,11是另一个组

在第二组为“正常”的组中,mod字段为11表示使用ST(i)操作数。在“奇怪”的群体中,它使指令的含义完全不同

例如,
DA F0
,您可能想表示
FIDIV eax
,实际上是指。。没有什么。那里的桌子上有个洞
DA C0
另一方面,您可能想表达的意思是

FIADD eax
,实际上是指
FCMOVB st(0),st(0)

机器指令
fidiv
不能应用于寄存器;它必须使用间接寻址从内存加载操作数。唯一参数的格式必须为
dword ptr常量[REGISTER]
。编写
fidiv
时,编译器根据函数堆栈帧的布局,将其替换为
fidiv dword ptr OFFSET[ebp]