接收分段错误

时间:2014-03-23 22:21:58

标签: nasm

您好我正在为一项作业制定一个因子计划。我收到了分段错误,我不确定原因。

section .data  ;constants
    nums:  db  13,21,14,25,34,63,23,23,42,0x32 ;numbers sum = 290 ave 29
    len:   db  $-nums
    nln:   db  0xA
    msg:   db  "Average",0xA
    mlen:  db  $-msg
section .bss   ;variables
    spot:   resb 1
    total:  resb 4
    ave:    resb 4
    ob1:    resb 1
    ob2:    resb 1
    ob3:    resb 1
section .text  ;code
    global _start

_start:
    sub esi,esi 
    mov byte [total],0

循环遍历nums矢量的所有变量

loop:
    mov esp,[nums+esi]
    call ptln
    call convert_ascii
    call print_conv
    add [total],esp
    mov ecx,total
    add esi,1
    cmp esi,10
    jmp ptave
    jmp loop

打印平均值

ptave:
    mov esp,[total]
    mov eax,4
    mov ebx,1
    mov ecx,msg
    mov edx,mlen
    int 0x80
    call convert_ascii
    call print_conv
    jmp exit

只是打印一个新行

ptln:
    mov eax,4
    mov ebx,1
    mov ecx,nln
    mov edx,1
    int 0x80
    ret

退出命令

exit:
    mov ebx,0
    mov eax,1
    int 0x80

convert_ascii:
    mov byte [ob1],0
    mov byte [ob2],0
    mov byte [ob3],0
    xor edx,edx
    mov eax,10
    div esp
mov [ob3],edx
    div esp
    mov [ob2],edx
    div esp
    mov [ob1],edx
    ret

print_conv:
    mov eax,4
    mov ebx,1
    mov ecx,ob1
    mov edx,1
    int 0x80

    mov ecx,ob2
    int 0x80

mov ecx,ob3
int 0x80

我知道问题始于$ mov esp,[nums + esi] $ line但我不知道出了什么问题。我添加了完整的代码,因为我不太了解我在做什么。

1 个答案:

答案 0 :(得分:1)

callret指令(可能int)隐式使用堆栈,因此需要esp指向正确的位置(即当前顶部当前线程的堆栈;或者您自己设置的某些堆栈的当前顶部)。由于您在代码中使用esp作为通用寄存器,因此您最终会访问您的应用程序在您执行时很可能无法访问的内存位置。 call

mov esp,[nums+esi]
call ptln  ; call tries to push the return address onto the stack, but esp
           ; now contains one of the values from nums: OOPS! -> segfault 

经验法则:使用esp作为通用寄存器,除非您真的,确实确定它是'可以这样做。


另一个潜在的问题是访问nums就好像它是一个双字数组,即使它被声明为一个字节数组。