Assembly 在asm中打印浮点

Assembly 在asm中打印浮点,assembly,x86,x86-64,Assembly,X86,X86 64,在C的帮助下,我有以下程序在asm中打印浮点: .section .rodata format: .ascii "Your number is: %f\n\0" .section .text .globl main main: lea format(%rip), %rdi mov $0b1000000001011001100110011001101, %xmm0 # the number 2.7 mov $0, %eax add $-8, %r

在C的帮助下,我有以下程序在asm中打印浮点:

.section .rodata
format: .ascii "Your number is: %f\n\0"
.section .text
.globl main
main:
    lea format(%rip), %rdi
    mov $0b1000000001011001100110011001101, %xmm0 # the number 2.7
    mov $0, %eax
    add $-8, %rsp
    call printf@plt
    add $8, %rsp
    mov $0, %eax
    ret
>>> p $xmm0
$2 = {
  v4_float = {[0] = 2.70000005, [1] = 0, [2] = 0, [3] = 0},
  v2_double = {[0] = 5.3194953090036137e-315, [1] = 0},
...
}
但是,我在将其与以下组件组装时出错:

int_c.s:7:错误:不支持的指令'mov'

您是否不允许在
xmm
寄存器中添加即时数据,或者上述程序出现了什么问题


更新:我编译了它,但我认为我的问题是
movq
接受8字节,但我希望在fp寄存器中得到一个4字节的浮点:

mov $2.7, %eax # using '2.7' to be more readable
movq %eax, %xmm0
在单步执行说明之后,在调用
printf
之前,它看起来是正确的:

.section .rodata
format: .ascii "Your number is: %f\n\0"
.section .text
.globl main
main:
    lea format(%rip), %rdi
    mov $0b1000000001011001100110011001101, %xmm0 # the number 2.7
    mov $0, %eax
    add $-8, %rsp
    call printf@plt
    add $8, %rsp
    mov $0, %eax
    ret
>>> p $xmm0
$2 = {
  v4_float = {[0] = 2.70000005, [1] = 0, [2] = 0, [3] = 0},
  v2_double = {[0] = 5.3194953090036137e-315, [1] = 0},
...
}

以下是程序的工作示例,将值写入内存,然后使用将浮点转换为双精度浮点:

format: .ascii "Your number is: %f\n\0"
.section .text
.globl main
main:
    push %rbp
    mov %rsp, %rbp
    lea format(%rip), %rdi

    # move float to memory and upgrade to 8 bytes
    movl $0b1000000001011001100110011001101, -4(%rbp)
    cvtss2sd -4(%rbp), %xmm0

    mov $1, %eax
    call printf@plt
    mov $0, %eax
    mov %rbp, %rsp
    pop %rbp
    ret

rax
将是
printf
中的浮点参数数。请参阅:。

事实上,这就是问题所在。当有疑问时,请参考指令集参考。@Jester当然,
movq
可以工作,但在添加时似乎仍然存在问题,因为数字显示
0
@Jester更新了问题。
printf
需要
双精度
所以它要查看gdb的低64位(
v2\u double
)这不是您想要的值。无论如何,将浮点常量输入寄存器的最典型方法是从内存加载。通常您希望在
.section.rodata
中使用
格式。文件顶部的默认部分是
.text
,因此您可以将其放在此处。另外,0-终止的正常方式是使用
.asciiz
,而不是使用显式
\0
.ascii
。此外,
cvtss2sd
也可以与寄存器一起工作,因此您不必遍历内存。除此之外,这对于未优化的代码也很好。不需要将RBP设置为帧指针,您可以
pushq$0b100000000101100111001101
对齐堆栈并存储浮点常量。(仍然只是读取它的低4字节,忽略符号扩展的高半部分。)@Jester我如何使用寄存器执行上述操作?我尝试从
rax
移动到
xmm0
,但当我尝试时,这给了我
0
;movd%eax,%xmm0;cvtss2sd%xmm0,%xmm0