根据装配的艺术CH14(死链接,在www.example.com上找不到archive.org)
14.4.4.1 指令
fld mem_32
fld mem_64[bx]
我的目标是加载一个常数10到我的FPU堆栈。为什么我不能这样做?
__asm
{
move bx, 0x0004;
fld dword ptr[bx] or fld bx;
//-------
fld 0x004; //Since it is 32 bits?
fild 0x004;
}
2条答案
按热度按时间vuktfyat1#
这里至少有三个地方可能出错。一是汇编程序的语法。二是指令集架构。三是内存模型(16位对32位,分段对扁平)。我怀疑提供的例子是针对16位分段架构的,因为8087来自那个时代,但c++编译器主要是在386+保护模式之后出现的。
8087 FPU不支持在通用寄存器(GPR)和浮点堆栈之间移动数据的指令。基本原理是浮点寄存器使用32、64或80位,而GPR只有16位宽。而是间接从内存移动数据。
示例
fld myRealVar
假定已提供标签(具有宽度):首先请注意,这些示例假定数据属于段
.data
,并且已使用以下内容初始化该段只有在此之后,内存位置
0x0004
才可能包含常量10。我强烈怀疑这种模型在你的内联c++系统中是不可用的。同样,在这里,汇编程序必须足够聪明,能够将每个标签与提供的宽度相关联,并在指令中编码。将整数加载到FPU的一种方法是使用堆栈:
在32位体系结构中,可以直接使用
esp
来指向栈顶,这可能是C++编译器的情况:一些内联汇编器可能能够使用局部变量,并自动用ebp/esp寄存器和正确的偏移量替换标签:
ezykj2lf2#
为清楚起见,请注意:BX确实是一个16位寄存器。它仍然存在,但FLD指令不支持它。前两行的语法应该是:
移动电子备份,4
fld电子束x
当在C/C++中内联时,编译器可能支持__asm styntax。上面的答案假设使用单独的汇编程序编译单独的ASM文件。