See wikipedia for the details of standard floating point format.
The double precision has a leading sign bit (0 for positive), then 11 bits of exponent biased by 1023, finally 52 bits of mantissa with an implicit leading 1. The number 2^-n
will have 0 sign and 0 mantissa (because the mantissa value is 1 but the leading 1 is omitted) and the exponent will be 1023-n
. It's easy to create this pattern by negation, addition and shift:
section .data
formatfloatinput db "%lf", 0
section .text
global main
extern printf
main:
push rbp ; maintain stack alignment
mov r12, 3 ; fetch input into r12 here, use 3 as example
neg r12 ; get -n
add r12, 1023 ; add the double-precision exponent bias
shl r12, 52 ; shift into place
; sign and mantissa are zero, we are done
movq xmm0, r12
mov rdi, formatfloatinput
mov eax, 1
call printf
xor eax, eax
pop rbp
ret
By the way, even though your code isn't optimial, it did seem to work for me after I have added the missing pieces.