Assembly NASM x86_64扫描分段故障
我是nasm的新手,我非常想学习如何使用用户输入存储数字。在使用scanf时,我无法摆脱分割错误。我在网上搜索过,但没有找到解决这个问题的办法。 我试过了,但对我不起作用 有人能解释一下我做错了什么吗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
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才重要,而不是保存/恢复寄存器。不过,推送/弹出通常效率更高。