Assembly Printf汇编语言堆栈指针nasm intel

Assembly Printf汇编语言堆栈指针nasm intel,assembly,nasm,Assembly,Nasm,安装程序:Nasm英特尔64位ubuntu 当我包含printf行时,我得到了一个分段错误。不包括它编译和运行良好。我只是想打印代码中的1 调用printf是否打印堆栈指针上的内容? 在这里调用printf时,DD2是否在堆栈指针处 我只是弹出最后两个项目,让堆栈返回其初始位置 感谢您的帮助,祝您今晚愉快 SECTION .data DD: db 1 DD2: db "%d" extern printf SECTION .text global main main:

安装程序:Nasm英特尔64位ubuntu 当我包含printf行时,我得到了一个分段错误。不包括它编译和运行良好。我只是想打印代码中的1

调用printf是否打印堆栈指针上的内容? 在这里调用printf时,DD2是否在堆栈指针处

我只是弹出最后两个项目,让堆栈返回其初始位置

感谢您的帮助,祝您今晚愉快

SECTION .data
DD:
    db 1
DD2:
    db "%d"
extern printf

SECTION .text
global main

main:
    push DD
    push DD2
    call printf
    pop rax ; 
    pop rbx ;

    ret

64位的调用约定与32位的调用约定大不相同

向下滚动至x86-64,它将告诉您前6个参数在寄存器中传递: RDI中的第一个参数、RSI中的第二个参数、RDX中的第三个参数、第四个RCX、第五个R8、第六个R9,并且它们在堆栈上传递;浮点参数在XMM0–7中传递

因此,printf调用应该是:

mov     rsi, DD
mov     rdi, DD2
mov     rax, 0
call    printf
因为在xmm注册表中没有传递任何内容,所以我们将rax设置为0(没有它可能会崩溃)

我还应该注意,堆栈必须是16字节对齐的,当程序启动并链接到c库时就是这样。但是,由于调用在堆栈(返回地址)上推送一个8字节的值,堆栈没有对齐。在函数开始时(在您的例子中是main),只需执行一个
子rsp,8
,就可以了