X86 如何在masm中相乘两个浮点变量

X86 如何在masm中相乘两个浮点变量,x86,masm,X86,Masm,如何将masm中的两个浮点变量相乘,汇编用户以3.02的形式输入一个输入,并将其与0.008相乘,然后打印它 .data fin dd 5.0 .code main proc fld fin fmul fin ;to multiply fin with fin fstp dword [eax] ;cannot mov result in eax call writefloat exit main EndP end main 如果要使用FPU,请记住它使用了一组堆叠的寄存器,这

如何将masm中的两个浮点变量相乘,汇编用户以3.02的形式输入一个输入,并将其与0.008相乘,然后打印它

.data 
fin dd 5.0

.code
main proc

fld fin
fmul fin  ;to multiply fin with fin 
fstp dword [eax]   ;cannot mov result in eax
call writefloat

exit 
main EndP
end main

如果要使用FPU,请记住它使用了一组堆叠的寄存器,这些寄存器只能从内存加载或保存到内存中。 我假设您可以自己记录FPU编程模型,或者使用,或者,如果您觉得怀旧的话,使用

指令fstp dword[eax]将st0的内容保存在eax表示的地址。这种寻址模式是一种间接寻址模式,在英特尔汇编语法中始终使用方括号进行标记。 这与在eax中保存st0形成对比,后者应该看起来像fstp eax,没有括号。 遗憾的是,后者不受支持,可能是因为FPU支持64位和80位格式,而这两种格式在当时无法适应任何寄存器

推送数据。从内存,到FPU堆栈使用fld,要弹出寄存器,到内存,如果不想弹出堆栈,请使用fstp或fst。 要使用fmul执行乘法,它有几种变体,其中一种变体可以使用内存操作数进行操作,并将结果直接存储在st0中

如果您感到偏执,可以在程序开始时使用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
此代码加载fin并将其乘以fin。这和fin^2的平方相同。fmul应将要乘以的值作为其操作数。但是代码与问题不符,因为fin是一个常数5.0,而你说的是乘以3.02x0.008。