繁体   English   中英

FASM汇编如何在64位程序中使用FPU

[英]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


更新#2msdn表示 ,对于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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM