Home > Software design >  Interaction with array results in a segfault
Interaction with array results in a segfault

Time:09-18

I'm trying to implement a simple addition calculator, but I'm not able to store the input in my array. I'm trying to read char by char because I want to use it later to implement a backend for my B compiler (which has the getchar function that reads char by char from stdin). My code is the fallowing:

segment .data
    numb db  0, 0, 0, 0
    indx db  0
    char db  '0'
    newl db  0ah

    msg1 db  'enter a number: '
    len1 equ $ - msg1

segment .text
global _start                       ; defines the entry point

print:                              ; push msg; push len
    pop   eax                       ; removes caller address from stack
    pop   edx                       ; gets length
    pop   ecx                       ; gets msg
    push  eax                       ; pushes CA to stack again

    mov   ebx ,   01h               ; tells that it's an output call
    mov   eax ,   04h               ; system call (write)
    int   80h                       ; calls it
    ret

getc:                               ; push add; push len
    pop   eax                       ; removes caller address from stack
    pop   ecx                       ; gets ouput addrress
    push  eax                       ; pushes CA to stack again

    mov   edx ,   01h
    mov   ebx ,   00h               ; tells that it's an input call
    mov   eax ,   03h               ; system call (read)
    int   80h                       ; calls it
    ret

exit:
    mov   ebx ,   0                 ; sets exit code
    mov   eax ,   01h               ; system call (exit)
    int   80h                       ; calls it

_start:
    push  msg1
    push  len1
    call  print

    read:
    push  char
    call  getc

    mov   eax ,   numb
    add   eax ,   indx
    mov  [eax],   dword char

    inc           byte [indx]

    mov   eax ,   char
    cmp   eax ,   newl
    jne   read

    jmp   exit                      ; exits program

for now I'm just trying to store the input, because I got segfaults from the complete code, so I started stripping off code until I found the error cause.

CodePudding user response:

You probably don't want to insert the newline in the array, so start with checking for the newline:

read:
    push  char
    call  getc
    mov   al, [char]
    cmp   al, 10
    je    done

Then load the byte-sized index in an address register, remembering that AL already contains the datum, so pick another register than EAX. Also, instead of adding the array address numb and the index indx yourself, let the CPU do that for your with an addressing mode that has a displacement component ([numb ebx]):

    movzx ebx, byte [indx]
    mov   [numb   ebx], al
    inc   byte [indx]
    jmp   read
done:
    jmp   exit

There's also the possibility to define the index indx as a dword with indx dd 0. Then the code becomes:

read:
    push  char
    call  getc
    mov   al, [char]
    cmp   al, 10
    je    done
    mov   ebx, [indx]
    mov   [numb   ebx], al
    inc   dword [indx]
    jmp   read
done:
    jmp   exit

The lesson here is that NASM is different from MASM in how you address memory:

MASM

mov eax, offset MyVar    ; Load address of MyVar
mov eax, MyVar           ; Load value stored in MyVar

NASM

mov eax, MyVar           ; Load address of MyVar
mov eax, [MyVar]         ; Load value stored in MyVar
  • Related