简体   繁体   English

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

[英]FASM assembly how to use the FPU in 64 bit programs

I have this code in FASM that calculates a measurement using the FPU that works great in 32 bit programs. 我在FASM中有此代码,该代码使用在32位程序中运行良好的FPU计算度量。 How would I convert it so it would run in 64 bit program. 我将如何转换它以便它可以在64位程序中运行。 when I use this code in the 64 bit program it gives me 0.00000 instead of a number like 54.24457 I think it is something with the FPU instructions but I don't know enough about assembly or 64 bit programming to get it to work 当我在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

} 

thanks 谢谢

The calling convention for doubles in 64 bit mode uses xmm registers, you'll have to adjust your cinvoke lines if it even supports that. 64位模式下双打的调用约定使用xmm寄存器,即使它支持,也必须调整您的cinvoke行。 Otherwise just use manual code, something like: 否则,只需使用手动代码,例如:

lea rcx, [buffer1]
lea rdx, [format]
movsd xmm0, [buffer3]
sub rsp, 32
call sprintf
add rsp, 32

Disclaimer: I don't have windows to test. 免责声明:我没有要测试的窗口。


Update : cinvoke is a helper macro that tries to do the right thing for calling a C function. 更新cinvoke是一个帮助程序宏,它试图为调用C函数做正确的事情。 You are passing the double in two parts, which might work for a stack-based calling convention, but in 64 bit mode registers are used to pass arguments. 您将分两部分传递双精度,这对于基于堆栈的调用约定可能有效,但是在64位模式下,寄存器用于传递参数。 For doubles you need to use xmm registers. 对于双打,您需要使用xmm寄存器。 The cinvoke macro might know how to do that, but you certainly need to help it by telling it you want to pass a double. cinvoke宏可能知道该怎么做,但是您肯定需要通过告诉它要传递双cinvoke来提供帮助。 The code I posted is a hopefully correct calling sequence for sprintf , as such you can use it instead of the cinvoke . 我发布的代码是sprintf正确调用序列,因此您可以使用它代替cinvoke


Update #2 : msdn says that for varargs functions (and sprintf is one) floating point arguments must be duplicated in both integer and xmm registers. 更新#2msdn表示 ,对于varargs函数( sprintf是其中之一),浮点参数必须在整数和xmm寄存器中均重复。 Here is a complete console program multiplying 2 values using the FPU: 这是一个完整的控制台程序,使用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

Note this is for nasm but you should be able to adapt this to your needs. 请注意,这是针对nasm但是您应该能够根据需要进行调整。 I have tested this using wine. 我已经用酒测试过了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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