title: Printing floating point numbers in assembler
body: <p>I'm trying to print a floating-point value from assemler calling a printf function. It works fine with strings and integer values but fails printing floats. Here is an example of working code:</p>
  
  <pre><code>global  main
  extern  printf
  
  section .data
    message:    db      "String is: %d %x %s", 10, 0
    end_message:    db    ".. end of string", 0 
  
  section .text
    main:
      mov eax, 0xff
      mov     edi, message
      movsxd rsi, eax
      mov rdx, 0xff
      mov rcx, end_message
      xor rax, rax
      call printf
      ret
  </code></pre>
  
  <blockquote>
    <p>String is: 255 ff .. end of string</p>
  </blockquote>
  
  <p>So, the parameters are passed through registers: <em>edi</em> contains address of a formatting string, <em>rsi</em> and <em>rdx</em> contain the same number to print in decimal and hex styles, <em>rcx</em> contains end of a string, <em>rax</em> contains 0 as we do not have a float to print.
  This code works fine but something changes while trying to print float:</p>
  
  <pre><code>global main
  
  extern printf
  
  section .data
      val: dq 123.456
      msg: db "Result is: %fl",10, 0
  
  section .text
      main:
      mov rdi,msg
      movsd xmm0,[val]
      mov eax,1
      call printf
  
      mov rax, 0
      ret
  </code></pre>
  
  <p>This code snipped can be compiled but returns segmentation fault being executed. It seems that the problem is in wrong value of <em>xmm0</em> but trying to change <strong>movsd xmm0,[val]</strong> to <strong>movsd xmm0,val</strong> gives an </p>
  
  <blockquote>
    <p>error: invalid combination of opcode and operands</p>
  </blockquote>
  
  <p>message.
  The compiler is NASM running on openSuSe 12.3</p>
  
  <p>Update. I tried to make a c program and produce a .S assembly. It gives a very weird solution:</p>
  
  <pre><code>main:
  .LFB2:
      .cfi_startproc
      pushq   %rbp
      .cfi_def_cfa_offset 16
      .cfi_offset 6, -16
      movq    %rsp, %rbp
      .cfi_def_cfa_register 6
      subq    $32, %rsp
      movl    %edi, -4(%rbp)
      movq    %rsi, -16(%rbp)
      movq    val(%rip), %rax
      movq    %rax, -24(%rbp)
      movsd   -24(%rbp), %xmm0
      movl    $.LC0, %edi
      movl    $1, %eax
      call    printf
      movl    $0, %eax
      leave
      .cfi_def_cfa 7, 8
      ret
  </code></pre>
  
  <p>Is it possible to write a simple printf example?</p>