Function C implemented in the x86 assembler when parameters are passed by reference


I am implementing a C defined function in assembler. The function is as follows

extern void swapNums(float* one,float* two,float* three);

A) swapNums accepts 3 references to a float, and then places the smallest of these 3 values in 'one', the middle value in 'two' and the largest of the three values in 'three'.

I want to know:

  1. Which registers are used to store the references to the 3 floats, i.e. Is it rsi,rdi,rdx... or is it xmm0,xmm1,xmm3 ...

  2. How do I change the value in *one, *two, *three so that i can satisfy A)

I am accustomed to implementing C functions in assembler when the parameters of the function are passed by value. For example when dealing with floating point parameters, I follow the conventions below:

section .data

    global <name of function>

<name of function>:
    movss [x1], xmm0 ; move the first parameter into memory location x1
    movss [x2], xmm1 ; move the second parameter into memory location x2
    movss [xNorm], xmm2 ; move the third parameter into memory location x3

and then link the object files of the .asm and .c files when creating an executable

I've got the exact same problem, and I figured it out.

rdi contains the literal address, [rdi] will 'point' to the value stored at that address; so the three addresses will be stored at rdi, rsi, and rdx (Linux, and Mac OS/X); or rcx, rdx, and r8 (Windows).

So then to move the actual values that need to be compared across to the SSE registers you need to use, movss xmm0, [rdi].

Finally to get the floats back across to the C program, you need to use movss [rdi], xmm0: this will move the value of xmm0 over to where rdi is 'pointing' to.