Assembly SEGSEV,输入操作码时出现分段故障
(我是在为NASM编写纯x86汇编,而不是在C/C++中编写的。) 当编译的二进制文件运行时,我遇到了一个分段错误-我知道这是一条由来已久的错误消息,但搜索seg错误的这个特定实例并没有取得任何效果: gdb表明故障发生在呼叫开始时的Assembly SEGSEV,输入操作码时出现分段故障,assembly,segmentation-fault,nasm,Assembly,Segmentation Fault,Nasm,(我是在为NASM编写纯x86汇编,而不是在C/C++中编写的。) 当编译的二进制文件运行时,我遇到了一个分段错误-我知道这是一条由来已久的错误消息,但搜索seg错误的这个特定实例并没有取得任何效果: gdb表明故障发生在呼叫开始时的输入616,0。我相信这与将旧的%rbp,将%rsp存储到%rbp,并减少%rsp字节的%rsp本地变量是一样的 有更多经验的人有没有关于为什么分割错误会在这里发生的提示?对于内存访问问题来说,这似乎是一个奇怪的地方——我想到的唯一一件事是,616可能会大大降低该值
输入616,0
。我相信这与将旧的%rbp
,将%rsp
存储到%rbp
,并减少%rsp
字节的%rsp
本地变量是一样的
有更多经验的人有没有关于为什么分割错误会在这里发生的提示?对于内存访问问题来说,这似乎是一个奇怪的地方——我想到的唯一一件事是,616可能会大大降低该值,但除此之外,它让我感到困惑。允许的大小是否有限制(可用内存总量除外)
任何帮助都将不胜感激
更新:
如果有帮助的话,这并不是一系列递归调用的结束:
(gdb) backtrace
#0 0x00000000004005e0 in user_func ()
#1 0x0000000000400e69 in if4 ()
#2 0xffffffffffffffff in ?? ()
#3 0xffffffffffffffff in ?? ()
#4 0x0000000000000000 in ?? ()
(gdb) frame 0
#0 0x00000000004005e0 in user_func ()
(gdb) disassemble
Dump of assembler code for function user_partition:
=> 0x00000000004005e0 <+0>: enterq $0x2b0,$0x0
0x00000000004005e4 <+4>: push %r15
0x00000000004005e6 <+6>: push %r12
0x00000000004005e8 <+8>: push %r13
0x00000000004005ea <+10>: push %r14
...
有没有可能我在推/弹出东西方面做错了什么?在我看来,离开前的POP是正确的…回溯中的
0x0000000000000
和0xffffffffffffffff
等值表明您在某个点上破坏了堆栈(覆盖了返回值或类似值)。堆栈指针很可能是垃圾,因此很有可能推到它会导致seg故障。可能只是堆栈溢出?与分配的堆栈大小相关的堆栈指针在哪里?Hm,因此对于某些上下文,我正在编写一个编译器,在没有某些优化的情况下运行它,会留下相同的ENTER 616,0命令,但没有seg错误。您知道其他命令会如何影响此调用吗?如何检查堆栈大小?另外,gdb中的回溯显示没有大量递归调用,这可能会有所帮助,因此我不太相信堆栈溢出。(更新的问题)原来我的问题与脏寄存器无关,其他地方的错误只是导致代码永远递归。你对“堆栈溢出”的猜测是正确的。我将把这个标记为答案,因为你帮了很多忙(并且确实提供了答案,作为评论)。
user_func:
ENTER 296, 0
PUSH R13 ; Saving any callee-saved registers used in main body
PUSH R15
PUSH R14
PUSH R12
; Only opcodes to MOV between temp registers and [ RBP - x ]
MOV RAX, 0
POP R12 ; Restoring the callee-saved registers
POP R14
POP R15
POP R13
LEAVE
RET