我是汇编新手,我尝试在 Windows (x64) 上使用 NASM 编写汇编程序来提取和打印浮点数的小数部分。但是,我的程序打印
Floating Point Part: 0.000000
而不是预期的 Floating Point Part: 0.500000
。
这是我当前的代码:
section .data
fmt db "Floating Point Part: %f", 10, 0
float_value dq 10.5
result dq 0.0
section .text
global main
extern printf
main:
; Function prologue
push rbp
mov rbp, rsp
sub rsp, 32 ; Allocate shadow space
; Load floating-point value into the FPU
fld qword [rel float_value]
; Call floatVal function
call floatVal
; Store result from the FPU to memory
fstp qword [rel result]
; Print the result using printf
lea rcx, [rel fmt] ; First argument: format string
lea rdx, [rel result] ; Second argument: address of result
movsd xmm0, qword [rdx] ; Move the double to xmm0 for printf
call printf
; Function epilogue
add rsp, 32 ; Deallocate shadow space
mov eax, 0
pop rbp
ret
floatVal:
; Function prologue
push rbp
mov rbp, rsp
sub rsp, 32 ; Allocate shadow space
; Get the integer part
fld st0 ; Copy the value to the top of the stack
frndint ; Round to integer
fsub ; Subtract integer part from original value (st0 - st1)
; Function epilogue
add rsp, 32 ; Deallocate shadow space
pop rbp
ret
编译与执行步骤:
nasm -f win64 flo.asm -o flo.o
gcc -m64 -o flo flo.o -lkernel32 -lmsvcrt
.\flo.exe
预期输出:
Floating Point Part: 0.500000
实际产量:
Floating Point Part: 0.000000
环境:
我尝试过的:
浮点运算看似执行了,但结果不是我所期望的。看起来结果可能被覆盖或未正确传递给 printf。
我到底需要知道什么
我对低级编程非常陌生,任何帮助或建议将不胜感激。
PS: 我发现之前在 StackOverflow 中发布的相同问题,并尝试更新引用它们的代码。他们不为我工作,我对重新发布表示歉意
根据调用约定,第二个参数进入
xmm1
而不是xmm0
。此外,它应该复制到rdx
。 “第二个参数:结果的地址” 没有任何意义,因为 printf
不需要双精度值的地址。你应该这样做:
lea rcx, [rel fmt] ; First argument: format string
movsd xmm1, [rel result] ; Move the double to xmm1 for printf
movq rdx, xmm1 ; duplicate second argument as per convention
call printf
此外,在 64 位模式下,您通常应该完全避免使用 x87 FPU。叶子函数不需要分配影子空间。