C/汇编子程序段错误

标签 c assembly segmentation-fault gdb

尝试通过 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 reglayout next 直到获得所需的窗口组合。)请参阅 的底部标记 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/

相关文章:

c - 在文件中搜索时出现段错误

c - 64 位可执行文件的运行速度比 32 位版本慢

c - Windows 上 C 的 IDE 建议

c - 为什么在链表的 C 实现中需要指针?

在 32 位和 64 位 Mac 上创建 hello world

assembly - nasm中$$的真正含义是什么

assembly - x64 代码中的对齐问题,Free Pascal

c - 让 gcc 以 "int 0x80"方式编译系统调用?

c - 尝试在 C 中读取迷宫文本文件时出现 malloc 错误

c - 为什么在写入使用字符串文字初始化的 "char *s"而不是 "char s[]"时出现段错误?