NASM printf打印64位双段错误 [英] NASM printf print 64 bit double segfaults

查看:35
本文介绍了NASM printf打印64位双段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正努力想办法在装配中打印双面纸,但我失败得很惨。在调用我自己的函数时,我得到了Segerror,我计划使用该函数作为帮助器来打印双精度值以进行调试。我遵循了这些printf示例:https://www.csee.umbc.edu/portal/help/nasm/sample.shtml

我的代码当前如下所示:

section .data
    formatStrf: db `The number is %f
`,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注册表,如下所示:

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

编辑:我正在Linux上运行此程序。

推荐答案

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

中列出

其基本原理是前6个整数/指针参数在RDI/rsi/rdx/rcx/r8/r9中传递,而前8个浮点/双精度参数在XMM0..XMM7中传递。此外,您需要指定用于AL2中参数的XMM寄存器的数量。因此,在您的示例中,您需要RDI格式、XMM0格式的双精度值和AL格式的1

wikipedia page也有很多有关此方面的(简明)信息。


1对于非Microsoft系统--MS就是MS,它们以自己不兼容的方式做事

2实际上只需要为使用至少一个XMM寄存器的varargs函数设置它。对于非varargs函数,它将被忽略,如果它对于varargs函数设置得太大,结果将是浪费几个周期(保存未生成的XMM正则),但实际上不会破坏任何东西。

这篇关于NASM printf打印64位双段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆