首页 > 解决方案 > 在 asm 中打印一个浮点数

问题描述

我有以下程序在 C 的帮助下打印 asm 中的浮点数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

但是,在组装时出现错误:

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

您是否不允许将立即数添加到xmm寄存器中,或者上述程序似乎有什么问题?


更新:我得到了编译,但后来我认为我的问题是movq接受 8 字节,但我希望将 4 字节浮点数放入 fp 寄存器:

mov $2.7, %eax # using '2.7' to be more readable
movq %eax, %xmm0

在逐步完成说明之后,在调用之前它看起来是正确的printf

>>> p $xmm0
$2 = {
  v4_float = {[0] = 2.70000005, [1] = 0, [2] = 0, [3] = 0},
  v2_double = {[0] = 5.3194953090036137e-315, [1] = 0},
...
}

标签: assemblyx86x86-64

解决方案


这是您的程序的一个工作示例,将值写入内存,然后cvtss2sd用于将浮点数转换为双精度:

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. 请参阅:为什么在调用 printf 之前将 %eax 归零?.


推荐阅读