【问题标题】:Printing a float in asm [duplicate]在asm中打印一个浮点数[重复]
【发布时间】:2021-06-22 20:31:03
【问题描述】:

我有以下程序在 C 的 printf 的帮助下在 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

但是,我在组装时遇到错误:

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},
...
}

【问题讨论】:

  • 确实是问题所在。如有疑问,请参阅指令集参考。
  • @Jester 当然,movq 有效,但添加它时似乎仍然存在问题,因为数字显示0
  • @Jester 更新了问题。
  • printf 需要 double,因此它将查看低 64 位(v2_double 到 gdb),这不是您想要的值。
  • 无论如何,将浮点常量放入寄存器的最典型方法是从内存中加载。

标签: assembly x86 x86-64


【解决方案1】:

这是您的程序的一个工作示例,将值写入内存,然后使用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 中浮点参数的数量。见:Why is %eax zeroed before a call to printf?

【讨论】:

  • 通常你需要format in .section .rodata。文件顶部的默认部分是.text,这就是您放置它的位置。此外,正常的 0 终止方式是使用 .asciiz,而不是使用显式 \0.ascii
  • 另外,cvtss2sd 也适用于寄存器,因此您不必遍历内存。
  • 除此之外,是的,这对于未优化的代码来说很好。无需将 RBP 设置为帧指针,您可以 pushq $0b1000000001011001100110011001101 对齐堆栈并存储浮点常量。 (仍然只读取它的低 4 个字节,忽略符号扩展的高半部分。)
  • @Jester 我怎么能用寄存器做上述事情?我尝试从rax 移动到xmm0,但是当我尝试时这给了我0
  • movl $0b1000000001011001100110011001101, %eax; movd %eax, %xmm0; cvtss2sd %xmm0, %xmm0
猜你喜欢
  • 1970-01-01
  • 2021-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多