[英]FASM assembly how to use the FPU in 64 bit programs
我在FASM中有此代码,该代码使用在32位程序中运行良好的FPU计算度量。 我将如何转换它以便它可以在64位程序中运行。 当我在64位程序中使用此代码时,它给出的是0.00000,而不是54.24457之类的数字,我认为这与FPU指令有关,但我对汇编或64位编程的了解不足,无法使其正常工作
macro calculateresultlengthX {
;calculate result length x
;formula is resultlengthX = resultlengthXpixelstextbox / MeasuredlengthXpixelstextbox * MeasuredlengthXtextbox
;read in resultlengthXinpixelstextbox
invoke GetDlgItemTextA, [hwnd], resultlengthxpixelstextbox, bufferbuffer1, 100
cinvoke sscanf, bufferbuffer1, "%f", buffer1
;read in MeasuredlengthXinpixelstextbox
invoke GetDlgItemTextA, [hwnd], measuredlengthxpixelstextbox, bufferbuffer2, 100
cinvoke sscanf, bufferbuffer2, "%f", buffer2
;resultlengthXpixels / MeasuredlengthXpixels
finit
fld dword [buffer1]
fld dword [buffer2]
fdivp
fstp qword [buffer3]
cinvoke sprintf, addr buffer1, "%.16lf", dword [buffer3], dword [buffer3 + 4]
invoke SetDlgItemTextA,[hwnd],resultlengthxtextbox,addr buffer1
;read in ResultlengthXtextbox to get the temporary value
invoke GetDlgItemTextA, [hwnd],resultlengthxtextbox, bufferbuffer1, 100
cinvoke sscanf, bufferbuffer1, "%f", buffer1
;read in MeasuredlengthXtextbox
invoke GetDlgItemTextA, [hwnd],measuredlengthxtextbox, bufferbuffer2, 100
cinvoke sscanf, bufferbuffer2, "%f", buffer2
;answer * MeasuredlengthXtextbox
finit
fld dword [buffer1]
fld dword [buffer2]
fmulp
fstp qword [buffer3]
cinvoke sprintf, addr buffer1, "%.16lf", dword [buffer3], dword [buffer3 + 4]
invoke SetDlgItemTextA,[hwnd],resultlengthxtextbox,addr buffer1
}
谢谢
64位模式下双打的调用约定使用xmm
寄存器,即使它支持,也必须调整您的cinvoke
行。 否则,只需使用手动代码,例如:
lea rcx, [buffer1]
lea rdx, [format]
movsd xmm0, [buffer3]
sub rsp, 32
call sprintf
add rsp, 32
免责声明:我没有要测试的窗口。
更新 : cinvoke
是一个帮助程序宏,它试图为调用C函数做正确的事情。 您将分两部分传递双精度,这对于基于堆栈的调用约定可能有效,但是在64位模式下,寄存器用于传递参数。 对于双打,您需要使用xmm
寄存器。 cinvoke
宏可能知道该怎么做,但是您肯定需要通过告诉它要传递双cinvoke
来提供帮助。 我发布的代码是sprintf
正确调用序列,因此您可以使用它代替cinvoke
。
更新#2 : msdn表示 ,对于varargs函数( sprintf
是其中之一),浮点参数必须在整数和xmm寄存器中均重复。 这是一个完整的控制台程序,使用FPU将2个值相乘:
global main
extern scanf
extern printf
main:
sub rsp, 40 ; shadow space + stack alignment
lea rcx, [infmt]
lea rdx, [op1]
call scanf
lea rcx, [infmt]
lea rdx, [op2]
call scanf
fld dword [op1]
fld dword [op2]
fmulp
fstp qword [result]
lea rcx, [outfmt]
movsd xmm1, [result]
mov rdx, [result]
call printf
add rsp, 40
xor eax, eax
ret
section .data
op1: dd 0
op2: dd 0
result: dq 0
infmt: db "%f", 0
outfmt: db "%.16lf", 0
请注意,这是针对nasm
但是您应该能够根据需要进行调整。 我已经用酒测试过了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.