簡體   English   中英

nasm組件中的printf float 64位

[英]printf float in nasm assembly 64-bit

我想用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

rs包含浮動值1.6

(gdb) x/fg &rs
0x600ad8 <rs>:  1.6000000000000001

但是程序打印

[username@localhost folder]$ ./programname
0.000000

誰可以獲得打印1.6的程序? 我究竟做錯了什么?

我懷疑問題與您的代碼將rax設置為0而它必須為1因為您傳遞了浮點參數(有關詳細信息,請參見此處 )。 基本上rax應該包含在xmmN寄存器中傳遞的變量參數的數量。

編輯:

printf的崩潰似乎是由於堆棧錯配引起的,因為該程序在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)

輸入main ,堆棧不是16字節對齊的,但是如果您對此進行修復,則程序可以正常工作。 下面是我的測試程序(請注意sub rsp, 8開頭是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

我究竟做錯了什么?

首先 :確保使用正確的調用約定(堆棧,寄存器,從左至右,從右至左等)。 如果您的程序確實打印了一個浮點數,盡管它不是您所需要的浮點數,那么至少格式字符串已正確傳遞(或者您很幸運, printf在右側找到了格式字符串的地址)即使您沒有在此處放置它的地址也可以)。

第二 :您要打印的數字...是浮點數還是雙精度數? rs定義為保留四字值(64位),但浮點數為32位。 因此,如果已經檢查了第一點並且沒問題,我建議您使用"%lf"作為格式,而不是"%f"

順便說一句:為什么你把RAX = 0 關於調用printf是什么意思?

更新:這可能對您有幫助。 反匯編一個愚蠢的程序( fc ):

#include <stdio.h>

main()
{
  float x;

  x = 1.6;
  printf ("%f\n", x);
}

$ gcc -c -S fc

$ less fs

        .file   "f.c"
        .section        .rodata
.LC1:
        .string "%f\n"
        .text
.globl main
        .type   main, @function
main:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        movq    %rsp, %rbp
        .cfi_offset 6, -16
        .cfi_def_cfa_register 6
        subq    $16, %rsp
        movl    $0x3fcccccd, %eax
        movl    %eax, -4(%rbp)
        movss   -4(%rbp), %xmm0
        cvtps2pd        %xmm0, %xmm0
        movl    $.LC1, %eax
        movq    %rax, %rdi
        movl    $1, %eax
        call    printf
        leave

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM