【问题标题】:Printing floating point numbers in assembler在汇编程序中打印浮点数
【发布时间】:2015-01-06 11:59:32
【问题描述】:

我正在尝试从调用 printf 函数的汇编程序中打印一个浮点值。它适用于字符串和整数值,但无法打印浮点数。下面是一个工作代码示例:

global  main
extern  printf

section .data
  message:    db      "String is: %d %x %s", 10, 0
  end_message:    db    ".. end of string", 0 

section .text
  main:
    mov eax, 0xff
    mov     edi, message
    movsxd rsi, eax
    mov rdx, 0xff
    mov rcx, end_message
    xor rax, rax
    call printf
    ret

字符串是:255 ff .. 字符串结尾

因此,参数通过寄存器传递:edi 包含格式化字符串的地址,rsirdx 包含要打印的相同数字在十进制和十六进制样式中,rcx 包含字符串的结尾,rax 包含 0,因为我们没有要打印的浮点数。 此代码工作正常,但在尝试打印浮点数时发生了一些变化:

global main

extern printf

section .data
    val: dq 123.456
    msg: db "Result is: %fl",10, 0

section .text
    main:
    mov rdi,msg
    movsd xmm0,[val]
    mov eax,1
    call printf

    mov rax, 0
    ret

这段代码可以编译,但会返回正在执行的分段错误。似乎问题出在 xmm0 的错误值上,但尝试将 movsd xmm0,[val] 更改为 movsd xmm0,val 会给出

错误:操作码和操作数的组合无效

消息。 编译器是运行在 openSuSe 12.3 上的 NASM

更新。我试图制作一个 c 程序并生成一个 .S 程序集。它提供了一个非常奇怪的解决方案:

main:
.LFB2:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $32, %rsp
    movl    %edi, -4(%rbp)
    movq    %rsi, -16(%rbp)
    movq    val(%rip), %rax
    movq    %rax, -24(%rbp)
    movsd   -24(%rbp), %xmm0
    movl    $.LC0, %edi
    movl    $1, %eax
    call    printf
    movl    $0, %eax
    leave
    .cfi_def_cfa 7, 8
    ret

可以写一个简单的printf例子吗?

【问题讨论】:

    标签: linux assembly printf nasm glibc


    【解决方案1】:

    对于您的汇编程序问题: 您需要在主程序启动之前对齐堆栈。

    插入

    sub rsp, 8
    

    就在main之后:

    然后在ret之前再次添加:

    add rsp, 8
    

    【讨论】:

    • 谢谢。它打印数字但段错误仍然存​​在:结果是:123.456000l 分段错误
    • 如果答案是您所提问题的解决方案,您可以优雅地接受它;-)
    • 非常感谢您的解决方案 :)
    猜你喜欢
    • 2021-04-16
    • 1970-01-01
    • 2019-10-14
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多