【发布时间】:2018-12-01 15:50:05
【问题描述】:
section .data
text db 'Put a number',10,0
scanform db '%d'
number dw 0
section .text
extern printf,scanf
global main
main:
push rbp
mov rbp,rsp
push rdi
push rsi
push rbx
mov rdi,text
mov rax,0
call printf
mov rsi,number
mov rdi,scanform
mov rax,0
call scanf
pop rbx
pop rsi
pop rdi
ret
这是我的代码,我整天都在编写其他代码,但现在当我调用 scanf 时,编写程序收到信号 SIGSEV,segfault... 在不同文件中指定第一行和最后一行。我不明白这个消息有人可以帮助我吗?
【问题讨论】:
-
您未对齐堆栈。另外,你忘了
pop rbp。 -
你能以正确的方式编写我的代码吗?
-
只需删除
push rdi/rsi/rbx以及三个pops,而是在ret之前添加pop rbp。正如保罗所说,你还应该在"%d"之后添加一个,0,尽管从技术上讲它是有效的,因为无论如何你后面都是零。 -
@Jester,第一次格式转换会覆盖零。然后 fscanf 继续读取格式,该格式现在不再以 null 结尾(对于几个字节,在 x86 内存中反向布局的 int)
-
好吧,您仍然需要添加
pop rbp。如果你必须保留那些无用的推送(问你的教授为什么他坚持保留调用者保存的寄存器和甚至没有被触及的rbx)然后添加另一个push来对齐堆栈。
标签: c assembly x86-64 calling-convention