Question

Hi I am working on a factorial program for an assignment. I am receiving a segmentation fault and I am not sure why.

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

a loop to go through all variables of the nums vector

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

to print the average

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

just printing a new line

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

exit command

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

I know the problem starts at the $mov esp,[nums+esi]$ line but I don't know what is wrong. I added the full code because I don't really understand what I am doing.

Was it helpful?

Solution

The call and ret instructions (and probably int) implicitly use the stack, and therefore require esp to point to the correct location (i.e. the current top of the current thread's stack; or the current top of some stack that you've set up yourself). Since you're using esp as a general-purpose register in your code you end up accessing memory locations that your application most likely doesn't have access to as soon as you execute e.g. a 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 

Rule of thumb: Do not use esp as a general-purpose register unless you're really, really sure that it's ok to do so.


Another potential problem is that nums is accessed as if it was an array of doubleword, even though it's declared as an array of bytes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top