Assembly NASM x86_64扫描分段故障

Assembly NASM x86_64扫描分段故障,assembly,nasm,x86-64,Assembly,Nasm,X86 64,我是nasm的新手,我非常想学习如何使用用户输入存储数字。在使用scanf时,我无法摆脱分割错误。我在网上搜索过,但没有找到解决这个问题的办法。 我试过了,但对我不起作用 有人能解释一下我做错了什么吗 global main extern printf, scanf section .data msg: db "Enter a number: ",10,0 format:db "%d",0 section .bss number resb 4 section .text

我是nasm的新手,我非常想学习如何使用用户输入存储数字。在使用scanf时,我无法摆脱分割错误。我在网上搜索过,但没有找到解决这个问题的办法。 我试过了,但对我不起作用

有人能解释一下我做错了什么吗

global main

extern printf, scanf

section .data
   msg: db "Enter a number: ",10,0
   format:db "%d",0

section .bss
   number resb 4

section .text
main:
   mov rdi, msg
   mov al, 0
   call printf

   push number
   push format
   call scanf
   ret
提前谢谢

通常不推送参数。此外,您还必须告诉一个参数计数可变的函数,您提供了多少个浮点参数

这项工作:

global main
extern printf, scanf

section .data
   msg: db "Enter a number: ",10,0
   format:db "%d",0

section .bss
   number resb 4

section .text
main:
   sub  rsp, 8       ; align the stack to a 16B boundary before function calls

   mov rdi, msg
   mov al, 0
   call printf

   mov rsi, number
   mov rdi, format
   mov al, 0
   call scanf

   add   rsp, 8      ; restore the stack
   ret

顺便说一句:如果你想处理浮点数,你必须在调用函数之前将堆栈对齐到16字节的边界。

我觉得有点奇怪,整数不需要堆栈对齐,但浮点需要。浮点数由寄存器(至少前八个)传递,因此不需要从堆栈中读取浮点数。但是我猜
printf
还是会从堆栈中推/弹出它们。@Zboson:我的GDB告诉我,XMM寄存器将存储在局部变量(堆栈)中。要存储XMM寄存器,内存必须对齐,这显然不是(或不正确)由glibc完成的。我不明白为什么它会存储在堆栈上。System V AMD64 ABI通过XMM0-7中的前八个浮点。@Zboson:Gnu以神秘的方式移动。:-)@Zboson:printf是一个可变函数,gcc为
VA_ARG
等生成代码的方式是将XMM寄存器溢出到堆栈中,以便它可以对它们进行索引(如果有的话)=0(glibc的printf是用C编写的,由gcc编译)。我用sub/add而不是push/pop修复了这个答案,只是为了让初学者明白,只有RSP才重要,而不是保存/恢复寄存器。不过,推送/弹出通常效率更高。