为什么Windows x64调用约定要求将XMM(FP)参数复制到整数寄存器,以用于变量函数(如printf)?
我试图在Windows上使用NASM汇编以下代码。printf函数应该采用xmm0到xmm2作为分数点参数。为什么我必须在RDX、R8和R9中放置分数参数?我是新手为什么Windows x64调用约定要求将XMM(FP)参数复制到整数寄存器,以用于变量函数(如printf)?,windows,assembly,floating-point,x86-64,calling-convention,Windows,Assembly,Floating Point,X86 64,Calling Convention,我试图在Windows上使用NASM汇编以下代码。printf函数应该采用xmm0到xmm2作为分数点参数。为什么我必须在RDX、R8和R9中放置分数参数?我是新手 global main extern printf section .data ;Area = pi * r^2 pi dq 3.141592653589793238 radius dq 10.0
global main
extern printf
section .data
;Area = pi * r^2
pi dq 3.141592653589793238
radius dq 10.0
fmt dq "Pi=%.10f radius=%.10f area=%.10f",10,0
section .bss
section .text
main:
push rbp
mov rbp,rsp
sub rsp,32 ;shadow space
mov rcx, fmt
movq xmm0, [pi]
movq rdx,xmm0
movq xmm1, [radius]
movq r8,xmm1
movq xmm2, [pi]
mulsd xmm2, xmm1; pi*r multiply scalar double
mulsd xmm2, xmm1; pi * r^2
movq r9,xmm2
call printf
add rsp, 32
leave
ret
分数参数的过程在Microsoft x64和System-V x64之间有很大不同。出现的问题是将为Linux设计的程序移植到windows上的NASM。代码在Jo Van Hoey的《开始x64汇编编程》一书中给出
在调用
printf
之前,您不应该在rax
中输入浮点参数(3)的数量吗?这是否回答了您的问题@迈克尔:不,那是system-v的。我的是专门针对Windows64的。以下是来自的书籍示例:“对于vararg或非totyped函数,任何浮点值都必须在相应的通用寄存器中复制……整数寄存器和浮点寄存器都必须包含该值,以防被调用方需要整数寄存器中的值”。它们似乎没有比这更详细的内容了。@Michael:很明显,设计的目的是简化可变函数的实现:将所有4个传入寄存器参数转储到阴影空间,形成一个包含所有参数的数组。但如果你需要知道哪个是FP,哪个是整数,那就不简单了。所以只要转储整数。