如何在masm中将两个float变量相乘
How to multiply two float variables in 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,请记住它使用了一组只能从内存加载或保存到内存的堆栈寄存器。
我假设您可以自己记录 FPU 编程模型,或者使用 Intel manual 1 or, if you feel nostalgic, by reading this 387 manual from Intel dated 05/26/1987.
指令fstp dword [eax]
将st(0)
的内容保存在由eax
表示的地址。这种寻址方式是一种间接寻址方式,在Intel汇编语法中一直用方括号标示。
将此与在 eax
中保存 st(0)
进行对比,它应该看起来像 fstp eax
(没有括号)。
las,后者不受支持,可能是因为 FPU 支持当时无法容纳任何寄存器的 64 位和 80 位格式。
推送数据。从内存进入 FPU 堆栈,使用 fld
,弹出寄存器,进入内存,使用 fstp
(如果不想弹出堆栈,则使用 fst
)。
要执行乘法,请使用 fmul
,它有几种变体,其中一种可以使用内存操作数进行运算,并将结果直接存储在 st(0)
.
中
如果你觉得偏执,你可以在程序开始时使用 finit
,该指令重置 FPU 的控制寄存器以将寄存器标记为空。
OS 应该已经以干净的状态启动您的进程。
这里有一个简单的例子:
.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
如何在 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 编程模型,或者使用 Intel manual 1 or, if you feel nostalgic, by reading this 387 manual from Intel dated 05/26/1987.
指令fstp dword [eax]
将st(0)
的内容保存在由eax
表示的地址。这种寻址方式是一种间接寻址方式,在Intel汇编语法中一直用方括号标示。
将此与在 eax
中保存 st(0)
进行对比,它应该看起来像 fstp eax
(没有括号)。
las,后者不受支持,可能是因为 FPU 支持当时无法容纳任何寄存器的 64 位和 80 位格式。
推送数据。从内存进入 FPU 堆栈,使用 fld
,弹出寄存器,进入内存,使用 fstp
(如果不想弹出堆栈,则使用 fst
)。
要执行乘法,请使用 fmul
,它有几种变体,其中一种可以使用内存操作数进行运算,并将结果直接存储在 st(0)
.
如果你觉得偏执,你可以在程序开始时使用 finit
,该指令重置 FPU 的控制寄存器以将寄存器标记为空。
OS 应该已经以干净的状态启动您的进程。
这里有一个简单的例子:
.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