繁体   English   中英

如何解决错误:我的代码中出现分段错误(核心转储)? AT&T 语法

[英]How do I solve the error: Segmentation fault(core dumped) in my code? AT&T syntax

我一直在寻找几个小时,我在我的代码中找不到错误。 该程序似乎在“opadd”标签处退出。 我在 Linux 上使用 x86_64,使用 AT&T 语法。

该程序将一个字符串作为输入,例如“2 3 add 4 mul”,然后,对于这个特定的示例,应该执行以下操作:

  • 将 2 添加到堆栈中
  • 将 3 添加到堆栈中
  • 计算 2 和 3 之和,然后将 5 添加到堆栈中
  • 将 5 和 4 相乘并将 20 添加到堆栈中,然后打印 20。
.data
    formatPrintf: .asciz "%d"
    sir: .space 1000
    delim: .asciz " "
    formatScanf: .asciz "%1000[^\n]"
    cuvant: .space 100
    primulNumar: .space 4
    atoiCuvant: .long 0
    x: .space 4
    y: .space 4
    eval: .long 0
    op: .space 4
    add: .asciz "add"
    sub: .asciz "sub"
    mul: .asciz "mul"
    div: .asciz "div"
.text

.global main

main:
    pushl $sir
    pushl $formatScanf
    call scanf
    popl %ebx
    popl %ebx
    
    pushl $delim
    pushl $sir
    call strtok
    popl %ebx
    popl %ebx
    
    pushl %eax
    call atoi
    popl primulNumar
    
    movl %eax, primulNumar
    
    pushl primulNumar
    
et_loop:
    pushl $delim
    pushl $0
    call strtok
    popl %ebx
    popl %ebx
    
    cmp $0, %eax
    je exit
    
    mov %eax, cuvant
    
    pushl %eax
    call atoi
    popl %ebx
    
    mov %eax, atoiCuvant
    
    cmp  $0, atoiCuvant
    je operatie
    
    pushl %eax
    
    jmp et_loop
    
operatie:
    
    push $cuvant
    push $add
    call strcmp
    popl %ebx
    popl %ebx
    
    cmp $0, %eax
    je opadd
    
    push $cuvant
    push $sub
    call strcmp
    popl %ebx
    popl %ebx
    
    cmp $0, %eax
    je opsub
    
    push $cuvant
    push $mul
    call strcmp
    popl %ebx
    popl %ebx
    
    cmp $0, %eax
    je opmul
    
    push $cuvant
    push $div
    call strcmp
    popl %ebx
    popl %ebx
    
    cmp $0, %eax
    je opdiv
    
opadd:
    popl %edx
    popl y
    
    add %edx, y
    push y
    
    jmp et_loop
    
opmul:
    popl %eax
    popl %ebx
    mul %ebx
    pushl %eax
    
    jmp et_loop
opdiv:
    popl %eax
    popl %ebx
    div %ebx
    pushl %eax
    
    jmp et_loop

opsub:
    popl %eax
    popl y
    sub %eax,y
    pushl y
    
    jmp et_loop

exit:
    popl eval
    
    pushl eval
    pushl $formatPrintf
    call printf
    popl %ebx
    popl %ebx
    
    pushl $0
    call fflush
    popl %ebx
    
    movl $1, %eax
    xorl %ebx, %ebx
    int $0x80
opadd:
    popl %edx <-- there IS a push without a pop on the first line of code, but...
    popl y <-- now there is nothing left in the stack

当您到达opadd时,似乎没有任何东西留在堆栈中。 et_loopoperatie中的每个push操作都有一个对应的pop 我还不能测试你的例子,因为你没有包括你的.data部分,但我几乎可以肯定这是问题所在。

mov %eax, cuvant pushl %eax call atoi popl %ebx

知道atoi是一个指针,我们看到cuvant变量将保存一个地址。

 operatie: push $cuvant push $add call strcmp popl %ebx popl %ebx

知道strcmp需要两个指针,我们看到这段代码传递了cuvant变量的地址,实际上它应该传递包含在cuvant变量中的地址(指向当前标记)。
因此,操作中的所有比较将失败。

 cmp $0, %eax je opdiv opadd:

当所有 4 次比较都失败时,代码就会在opadd:中失败 没有什么好期待的!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM