如何在masm中将两个浮点变量相乘,汇编用户输入一个输入为3.02并将其乘以0.008然后将其打印
=IF(IDENTIC($M$10;"Entries are correct.");IF(ISNUMBER(FIND("A1";$N$5));"S1";IF(ISNUMBER(FIND("A1";$N$6));"S2";IF(ISNUMBER(FIND("A1";$N$7));"S3";IF(ISNUMBER(FIND("A";$N$8));"S4";IF(ISNUMBER(FINDEN("A1";$N$9));"S5";"")))));"")
答案 0 :(得分:0)
如果你想使用FPU,请记住它使用了一组堆叠的寄存器,这些寄存器只能从存储器加载或保存到存储器中。
我假设您可以自己记录FPU编程模型,可以使用Intel manual 1,如果您感到怀旧,可以reading this 387 manual from Intel dated 05/26/1987。
指令fstp dword [eax]
将st(0)
的内容保存在 eax
表示的地址。这种寻址模式是间接寻址模式,并且在英特尔汇编语法中始终使用方括号标记。
相比之下,在st(0)
中保存eax
,看起来应该是fstp eax
(无括号)。
唉,后者不受支持,可能是因为FPU支持当时不适合任何寄存器的64位和80位格式。
推送数据。从内存进入FPU堆栈使用fld
,将寄存器弹出到内存中,使用fstp
(或fst
如果你不想弹出堆栈)。登记/>
要执行乘法运算fmul
,它有几个变体,其中一个可以使用内存操作数操作并将结果直接存储在st(0)
中。
如果您感到偏执,可以在程序开始时使用finit
,该指令会复位FPU的控制寄存器以将寄存器标记为空。
操作系统应该已经以干净状态启动您的进程。
这是一个简单的例子:
.DATA
A dd 5.0
B dq 0.008
C dd 0 ;Move into a BSS section if the assembler support it
.CODE
finit ;For paranoid only
fld DWORD [A] ;ST(0) = A
fmul QWORD [B] ;ST(0) = ST(0)*B = A*B
fstp DWORD [C] ;C = ST(0) = A*B
mov eax, DWORD [C] ;EAX = C = A*B
call writefloat
今天你可以使用带有标量指令的向量寄存器 您可以在之前链接的英特尔手册中找到相关文档。
.DATA
A dd 5.0 ;Use float
B dd 0.008 ;Use float again, avoid cvtss2sd
C dd 0 ;Move into a BSS section if the assembler support it
.CODE
movss xmm0, DWORD PTR [A] ;xmm0.f[0] = A
mulss xmm0, DWORD PTR [B] ;xmm0.f[0] = A * B
movd eax, xmm0 ;eax = xmm0.f[0] = A * B
;Beware, 1 extra cycle for bypass delay
call writefloat