почему перемещение float в xmm0 приводит к выводу 0

Хотите напечатать значение с плавающей запятой через printf в сборке

    segment .data
float_fmt   db  "%f", 0xa, 0
fp  dd  1.1

    segment .text
    global  main
    extern  printf
main:
    push    rbp
    mov rbp, rsp
    lea rdi, [float_fmt]
    movss   xmm0, [fp]
    mov eax, 1
    call    printf
    leave
    ret

Я хочу напечатать число с плавающей запятой одинарной точности (дд, 4 байта), однако printf печатает 0,000000 Изменение

fp dd 1.1 

to

fp dq 1.1 ; store double-precision floating-point(dq, 8 bytes)

а также

movss xmm0, [fp]

to

movsd xmm0, [fp] ; move double-precision floating-point (8 bytes)

решает проблему. Не могли бы вы объяснить, почему?


person Bulat M.    schedule 16.09.2016    source источник
comment
float varargs повышаются до double.   -  person Margaret Bloom    schedule 16.09.2016
comment
В этом случае, как печатать ровно поплавки (4 байта) со строкой формата %f, которая не удваивается? Следует ли всегда приводить float к double перед передачей в регистры xmm*?   -  person Bulat M.    schedule 16.09.2016
comment
@BulatM.: да, вы не можете указать printf интерпретировать аргумент как число с плавающей запятой, только двойное или длинное двойное число, поэтому вы должны использовать cvtss2sd вместо movss.   -  person Peter Cordes    schedule 16.09.2016
comment
Имеет размер double 4 байта и размер long double 8 байт?   -  person Bulat M.    schedule 16.09.2016
comment
double — 8 байт, long double — 10 байт (если IIRC)   -  person Margaret Bloom    schedule 16.09.2016