printf float in nasm assembly 64-bit

use*_*943 1 assembly printf x86-64 nasm calling-convention

我想用printf打印浮点值

global main
extern printf

section .data
   string: db `%f\n`, 0

section .bss
   rs: resq 1

[...]

   movq xmm0, [rs]
   mov rdi, string
   mov rax, 0
   call printf
Run Code Online (Sandbox Code Playgroud)

rs包含浮点值1.6

(gdb) x/fg &rs
0x600ad8 <rs>:  1.6000000000000001
Run Code Online (Sandbox Code Playgroud)

但程序打印

[username@localhost folder]$ ./programname
0.000000
Run Code Online (Sandbox Code Playgroud)

谁能让程序打印1.6?我究竟做错了什么?

szx*_*szx 6

我怀疑问题与你的代码设置有关rax,0而它必须是1因为你传递一个浮点参数(详见这里).基本上rax应该包含xmmN寄存器中传递的变量参数的数量.

编辑:

崩溃printf似乎是由堆栈miaslignment引起的,因为程序在一条movaps指令崩溃(它希望内存操作数在16字节边界上对齐):

=> 0x7ffff7a65f84 <__printf+36>:    movaps %xmm0,0x50(%rsp)
   0x7ffff7a65f89 <__printf+41>:    movaps %xmm1,0x60(%rsp)
   0x7ffff7a65f8e <__printf+46>:    movaps %xmm2,0x70(%rsp)
   0x7ffff7a65f93 <__printf+51>:    movaps %xmm3,0x80(%rsp)
   0x7ffff7a65f9b <__printf+59>:    movaps %xmm4,0x90(%rsp)
   0x7ffff7a65fa3 <__printf+67>:    movaps %xmm5,0xa0(%rsp)
   0x7ffff7a65fab <__printf+75>:    movaps %xmm6,0xb0(%rsp)
   0x7ffff7a65fb3 <__printf+83>:    movaps %xmm7,0xc0(%rsp)
Run Code Online (Sandbox Code Playgroud)

进入main堆栈时不是16字节对齐,但如果你解决这个问题,程序运行正常.下面是我的测试程序(注意sub rsp, 8开头):

global main
extern printf

section .data
    string db `%f\n`, 0
    rs dq 1.6

section .text

main:
    sub rsp, 8
    movq xmm0, qword [rs]
    mov rdi, string
    mov rax, 1
    call printf
    add rsp, 8
    mov eax, 0x60
    xor edi, edi
    syscall
Run Code Online (Sandbox Code Playgroud)