NASM printf打印64位双段错误

问题描述 投票:0回答:2

我正在努力使组装时的打印精度提高一倍,但我失败了。调用自己计划用作帮助程序的双打打印功能时,我遇到了段错误。我正在关注以下printf示例:https://www.csee.umbc.edu/portal/help/nasm/sample.shtml

我的代码当前看起来像这样:

section .data
    formatStrf: db `The number is %f\n`,0

section .text

extern printf

printfcallfloat:

    ;Pass in RDI
    PUSH RDI ;Preserve value of rdi
    PUSH RAX ;Preserve value of RAX

    PUSH RDI;The value we want to print
    PUSH DWORD formatStrf
    CALL printf ;Segfault

    POP RAX;Pop the stack back (too lazy to manually change the RSP value)
    POP RAX

    POP RAX;Restore the RAX and RDI
    POP RDI
    RET

我将浮点值传递给RDI reg,如下所示:

MOVSD QWORD [RSP], XMM0 ;Copy to stack
MOV RDI, QWORD [RSP]
CALL printfcallfloat

编辑:我正在linux上运行它。

assembly segmentation-fault printf x86-64
2个回答
2
投票

在x86_64上,参数在寄存器中传递,而不在堆栈中传递(仅当参数的大小太大而无法容纳在寄存器中时,才使用堆栈)。所有gory细节1都列在SYSV ABI for x86_64

基本原理是,前6个整数/指针参数在RDI / RSI / RDX / RCX / R8 / R9中传递,而前8个浮点/双精度参数在XMM0..XMM7中传递。此外,您需要指定用于AL 2中的参数的XMM寄存器的number。因此,您需要使用RDI中的格式,XMM0中的double值和AL中的1]

wikipedia page对此也有很多不错的信息。


1

对于非Microsoft系统-MS为MS,它们以自己不兼容的方式进行操作

2

您实际上只需要为使用至少一个XMM寄存器的varargs函数设置此项。对于非varargs函数,它将被忽略,如果对于varargs函数将其设置得太大,结果将是一些浪费的周期(保存未使用的XMM regs),但实际上不会破坏任何内容。

0
投票

您链接到的页面具有x86(32位体系结构的示例)。 x86_64体系结构在将参数传递给函数的方式上有所不同。

© www.soinside.com 2019 - 2024. All rights reserved.