Linux 在x86_64 AT&;中调用scanf时出现分段错误;T
我对汇编非常陌生,我正在尝试创建一个使用scanf从用户那里接收数字的程序。然后输出“结果:(数字)” 在运行代码时,我不断遇到分段错误。 这是我现在得到的代码:Linux 在x86_64 AT&;中调用scanf时出现分段错误;T,linux,assembly,x86-64,att,Linux,Assembly,X86 64,Att,我对汇编非常陌生,我正在尝试创建一个使用scanf从用户那里接收数字的程序。然后输出“结果:(数字)” 在运行代码时,我不断遇到分段错误。 这是我现在得到的代码: .global main mystring: .asciz"input\n" formatstring: .asciz" %d" resultstring: .asciz "Result: %ld\n" main: movq $0, %rax movq $mystring, %rdi ca
.global main
mystring: .asciz"input\n"
formatstring: .asciz" %d"
resultstring: .asciz "Result: %ld\n"
main:
movq $0, %rax
movq $mystring, %rdi
call printf
call inout
movq $0, %rax
movq $resultstring, %rdi
call printf
jmp end
inout:
pushq %rbp
subq $8, %rsp
leaq -8(%rbp), %rsi
movq $formatstring, %rdi
movq $0, %rax
call scanf
popq %rbp
ret
end:
movq $0, %rdi
call exit
我怀疑“inout”方法有问题。有什么解决方案可以让这个程序工作吗
在本说明中,您指的是
%rbp
寄存器,但您忘记实际初始化它 在inout
中,不设置rbp
,只在堆栈上推送旧值,然后访问rbp-8
内存(访问发生在scanf内部),该内存可能指向任何位置。顺便说一句,“我一直在得到一个分段错误”表明您方面缺乏努力,通过调试,您应该能够分辨出它在哪个指令发生故障,以及CPU的状态(寄存器值、代码地址、堆栈内容)。。。但在这一点上,你不需要这样问,因为你可能会自己看到scanf
的%rsi
参数是假的。而且在scanf调用后,你不恢复rsp
,而是使用错误的rsp
值执行pop%rbp
。此外,您还应确保在调用scanf
时对齐rsp
。检查此项:(看起来足够短,可能完成,4秒钟快速查看)此处可以找到关于类似问题的一些注释:一个推送和一个子rsp,8个堆栈也未对齐。ABI要求在运行调用(推送8B返回地址)之前对其进行16B对齐。
leaq -8(%rbp), %rsi