Why does the Windows x64 calling convention require XMM (FP) args copied to integer registers, for variadic functions like printf?

Viewed 103

I am trying to assemble following code using NASM on Windows. The printf function is supposed to take xmm0 through xmm2 for fractional point arguments. Why do I have to place fractional arguments in RDX, R8 and R9? Novice here.

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

The procedure for fractional arguments is quite different between Microsoft x64 and System-V x64. The problem arose will porting the program designed for Linux to NASM on windows. The code is given in book 'Beginning x64 Assembly Programming' by Jo Van Hoey.

https://github.com/mabs239/beginning-x64-assembly-programming/blob/master/Chapter%2042/42%20variadic1/variadic1.asm

https://github.com/mabs239/beginning-x64-assembly-programming/blob/master/Chapter%2012/12%20function2/function2.asm

0 Answers
Related