尝试通过 GDB 运行,一旦 C 主程序进入 main 函数,就会不断出现段错误。
GDB 错误:
Breakpoint 1, main () at binom_main.c:7
7 n=10;
(gdb) s
10 0;
(gdb) s
12 +){
(gdb) s
Program received signal SIGSEGV, Segmentation fault.
0x00000000004005c4 in otherwise ()
(gdb)
我这样编译代码:
as binom.s -o binom.o
gcc -S -Og binom_main.c
gcc -c binom_main.s
gcc binom_main.o binom.o -o runtimes
我试图在这里学习如何更有效地使用 GDB,但是像这样的段错误非常模糊且具有限制性。为什么在函数开始时会出现这个段错误?我是否错误地链接了这两个文件?
主要:
#include <stdio.h>
unsigned int result,m,n,i;
unsigned int binom(int,int);
int main(){
n=10;
i=0;
for (i=1; i<2;i++){
result = binom(n,i);
printf("i=%d | %d \n", i, result );
}
return 0;
}
子:
.text
.globl binom
binom:
mov $0x00, %edx #for difference calculation
cmp %edi, %esi #m=n?
je equalorzero #jump to equalorzero for returning of value 1
cmp $0x00, %esi #m=0?
je equalorzero
cmp $0x01, %esi #m=1?
mov %esi,%edx
sub %edi, %edx
cmp $0x01, %edx # n-m = 1 ?
je oneoronedifference
jmp otherwise
equalorzero:
add $1, %eax #return 1
call printf
ret
oneoronedifference:
add %edi, %eax #return n
ret
otherwise:
sub $1, %edi #binom(n-1,m)
call binom
sub $1, %esi #binom(n-1,m-1)
call binom
ret
最佳答案
当您使用 gdb 调试 asm 时,请查看反汇编窗口以及源代码窗口。 (例如 layout asm
/layout reg
和 layout next
直到获得所需的窗口组合。)请参阅 x86 的底部标记 wiki 以获取更多提示和文档链接。
您可以使用 stepi
(si
) 逐步执行指令,而不是使用 C 语句,同时调查汇编语言外部的崩溃(由于返回前损坏某些内容而导致)。
这看起来像一个错误:
sub $1, %edi #binom(n-1,m)
call binom
# at this point, %edi no longer holds n-1, and %esi no longer holds m.
# because binom clobbers them. (This is normal)
# as Jester points out, you also don't save the return value (%eax) from the first call anywhere.
sub $1, %esi #binom(n-1,m-1)
call binom
<小时/>
另一个(小?)错误是:
cmp $0x01, %esi #m=1?
# but then you never read the flags that cmp set
<小时/>
另一个严重的错误:
equalorzero:
add $1, %eax #return 1 # wrong: nothing before this set %eax to anything.
# mov $1, %eax # You probably want this instead
ret
关于C/汇编子程序段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38416114/