You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SASM中使用XMM0寄存器传递浮点数至printf失效的问题求助

SASM中使用XMM0寄存器传递浮点数至printf失效的问题求助

你遇到的问题核心是x86-64调用约定的细节处理不当,结合你教授提到的XMM寄存器用法,我们分场景来清晰解决:

问题根源

在x86-64汇编调用C标准库函数时,不同的调用约定(System V AMD64 vs Microsoft x64)对参数传递的要求完全不同:

  • 你教授要求的XMM寄存器传参,是System V AMD64调用约定(Linux/macOS默认)的规则
  • 你当前代码用RCX/RDX传参的方式,是Microsoft x64调用约定(Windows默认)的规则

你当前的代码混合了两种约定的用法,导致XMM寄存器传参失效。


解决方案1:遵循System V AMD64调用约定(符合你教授的要求)

在System V约定中,调用变参函数(如printf)需要满足三个关键规则:

  1. 浮点数参数通过XMM0~XMM7传递
  2. 必须设置RAX寄存器,告诉函数你使用了多少个XMM寄存器传递浮点数参数
  3. 整数/指针参数通过RDI, RSI, RDX, RCX, R8, R9依次传递(第一个参数用RDI,而非你当前用的RCX)

修改后的完整代码如下:

section .data
promptInput db "Enter two doubles: ", 10, 0
scanformat db "%lf", 0
printOpeOne db "OperandOne: %lf", 10, 0
printOpeTwo db "OperandTwo: %lf", 10, 0

section .bss
operandOne resq 1
operandTwo resq 1

section .text
bits 64
default rel
global main
extern printf, scanf

main:
; Print prompt
SUB RSP, 8*5
LEA RDI, [promptInput]  ; 第一个参数用RDI(System V约定)
CALL printf
ADD RSP, 8*5

; Read first double
SUB RSP, 8*5
LEA RSI, [operandOne]   ; 第二个参数用RSI
LEA RDI, [scanformat]   ; 第一个参数用RDI
CALL scanf
ADD RSP, 8*5

; Read second double
SUB RSP, 8*5
LEA RSI, [operandTwo]
LEA RDI, [scanformat]
CALL scanf
ADD RSP, 8*5

; Print first input
SUB RSP, 8*5
MOVSD XMM0, [operandOne]  ; 浮点数传入XMM0
MOV RAX, 1                ; 告诉printf:用了1个XMM参数
LEA RDI, [printOpeOne]
CALL printf
ADD RSP, 8*5

; Print second input
SUB RSP, 8*5
MOVSD XMM0, [operandTwo]
MOV RAX, 1
LEA RDI, [printOpeTwo]
CALL printf
ADD RSP, 8*5

XOR RAX, RAX
RET

解决方案2:如果你必须使用Microsoft x64调用约定(Windows环境)

在Windows的Microsoft约定中,printf作为变参函数时,浮点数参数需要同时传递到XMM寄存器和栈上的对应位置,因为变参函数会优先从栈上读取参数:

; 仅修改你的打印部分代码即可
; Print first input
SUB RSP, 8*5
MOVSD XMM0, [operandOne]
MOVQ [RSP + 8], XMM0     ; 将XMM0的内容同步到栈上的第二个参数位置
LEA RCX, [printOpeOne]
CALL printf
ADD RSP, 8*5

; Print second input
SUB RSP, 8*5
MOVSD XMM0, [operandTwo]
MOVQ [RSP + 8], XMM0     ; 同步到栈
LEA RCX, [printOpeTwo]
CALL printf
ADD RSP, 8*5

为什么你之前的代码不工作?

  • 如果你用的是System V环境:你错误地用了RCX/RDX传递参数(应该是RDI/RSI),且没有设置RAX告诉printf有XMM参数
  • 如果你用的是Microsoft环境:你只把浮点数放到了XMM0,但printf作为变参函数会从栈上读取参数,而栈上是未初始化的垃圾值,所以打印错误

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 11:54:38