Tuesday, December 17, 2013

Passing double to printf in XMM register

As last time all this happens on Linux and processor is 64 bit AMD. We want to call C function printf and to print float. Last time we used up to six registers to pass integers and %rdi for format string to printf and now we are going to use XMM registers and %rax to specify how many XMM registers we want printed. Compiling and linking is described in previous blog entry. I will actually use double which is 64 bit float. Here is the code:

.section .data
whatever:
    .int 3
double1:
    .double -1.234, 5.6789
double2:
    .double 123.456789
double3:
    .double 9.876, 5.4321
format:
    .asciz "have %d doubles %lf, %g, %g\n"
.section .text
.globl _start
_start:   
    nop
    movupd double3, %xmm2
    movdqu double1, %xmm1
    movsd double2, %xmm0
    movq whatever, %rsi
    movq $format, %rdi
    movq $3, %rax
    call printf
    call exit


Different MOV commands are used to load data into different XMM registers. One can use gdb to see what is loaded and where. Some will load single double into low half of register and some will load both doubles into register. Function printf will print only low half of register. XMM registers are in this call behaving as stack so the first float param is in %xmm0, the second one is in %xmm1 and so on.

No comments:

Post a Comment