0

我在 FASM 中有这段代码,它使用在 32 位程序中运行良好的 FPU 计算测量值。我将如何转换它以便它可以在 64 位程序中运行。当我在 64 位程序中使用此代码时,它给了我 0.00000 而不是像 54.24457 这样的数字

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

} 

谢谢

4

1 回答 1

1

64 位模式下双打的调用约定使用寄存器,如果它甚至支持xmm,您将不得不调整您的行。cinvoke否则只需使用手动代码,例如:

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

免责声明:我没有要测试的窗口。


Update :cinvoke是一个帮助宏,它试图为调用 C 函数做正确的事情。您在两部分中传递双精度,这可能适用于基于堆栈的调用约定,但在 64 位模式下,寄存器用于传递参数。对于双打,您需要使用xmm寄存器。宏可能知道如何做到这cinvoke一点,但您当然需要通过告诉它您想要传递一个双精度来帮助它。我发布的代码是一个希望正确的调用序列sprintf,因此您可以使用它而不是cinvoke.


更新#2msdn 说对于可变参数函数(并且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但您应该能够根据您的需要进行调整。我已经用葡萄酒对此进行了测试。

于 2013-10-16T16:05:20.867 回答