title: Beginner Tutorial: Assembler, Segmentation fault
body: <p>i am a beginner @coding and this is my first question here on stack overflow, although some of your great answers brought me some way along already.. </p>
  
  <p>While trying this <a href="http://asmtutor.com/#lesson16" rel="nofollow noreferrer" title="assembler-tutorial">assembler-tutorial</a> I am facing a segmentation fault after running the program. I tried to comment every line out and noticed that the programm crashes when I "call printString" on Line 30.</p>
  
  <p>When I try to debug with gdb (heck, i don't really know what i'm doing there..) i get an error inside the function "iterateChar" in my lenString call. (inside from my functions file - baseOperators.asm - line 50)</p>
  
  <p>I suspect, that somehow i messed up information in the eax register, but i don't know why, what has happened and how to fix this. My code looks very similar to the one from tutorial 16 on asmtutor.com - i c&amp;p'ed that, and that worked - for whatever reason. Please help.</p>
  
  <p>(i'm compiling with "$ nasm -f elf assemblerTutorial.asm" + "$ ld -m elf_i386 assemblerTutorial.o -o assemblerTutorial)</p>
  
  <pre><code>;------------------------------------------
  ; my Assembler learning Environment
  
  ;%include "calculate.asm"
  %include "baseOperators.asm"
  %include "print.asm"
  
  SECTION .text
  
  global _start
  
  _start:
  
      pop ecx         
      mov edx,    0
  
  argumentsLoop:
      cmp ecx,    0h      
      jz  argumentsEnd        
      pop eax         
  
      call    atoi            
  
      add edx,    eax     
      dec     ecx         
      jmp argumentsLoop       
  
  argumentsEnd:
      mov eax,    edx
      call    printString
      call    breakLine
      call    quit
  </code></pre>
  
  <p>my baseOperators.asm:</p>
  
  <pre><code>;------------------------------------------
  ; int atoi(Integer number)
  ; Ascii to integer function (atoi)
  atoi:
      push    ebx         ; preserve ebx on the stack to be restored after function runs
      push    ecx         ; preserve ecx on the stack to be restored after function runs
      push    edx         ; preserve edx on the stack to be restored after function runs
      push    esi         ; preserve esi on the stack to be restored after function runs
      mov esi,    eax     ; move pointer in eax into esi (our number to convert)
      mov eax,    0       ; initialise eax with decimal value 0
      mov ecx,    0       ; initialise ecx with decimal value 0
  
  .conversionLoop:
      xor ebx,    ebx     ; resets both lower and uppper bytes of ebx to be 0
      mov bl, [esi+ecx]   ; move a single byte into ebx register's lower half
      cmp bl, 48      ; compare ebx register's lower half value against ascii value 48 (char value 0)
      jl  .conversionEnd      ; jump if less than to label finished
      cmp bl, 57      ; compare ebx register's lower half value against ascii value 57 (char value 9)
      jg  .conversionEnd      ; jump if greater than to label finished
      cmp bl, 10      ; compare ebx register's lower half value against ascii value 10 (linefeed character)
      je  .conversionEnd      ; jump if equal to label finished
      cmp bl, 0       ; compare ebx register's lower half value against decimal value 0 (end of string)
      jz  .conversionEnd      ; jump if zero to label finished
      sub bl, 48      ; convert ebx register's lower half to decimal representation of ascii value
      add eax,    ebx     ; add ebx to our interger value in eax
      mov ebx,    10      ; move decimal value 10 into ebx
      mul ebx         ; multiply eax by ebx to get place value
      inc ecx         ; increment ecx (our counter register)
      jmp .conversionLoop     ; continue multiply loop
  
  .conversionEnd:
      mov ebx, 10         ; move decimal value 10 into ebx
      div ebx         ; divide eax by value in ebx (in this case 10)
  
      pop esi         ; restore esi from the value we pushed onto the stack at the start
      pop edx         ; restore edx from the value we pushed onto the stack at the start
      pop ecx         ; restore ecx from the value we pushed onto the stack at the start
      pop ebx         ; restore ebx from the value we pushed onto the stack at the start
      ret
  
  
  ;------------------------------------------
  ; int lenString(String message)
  ; String length calculation function
  lenString:
      push    ebx
      mov     ebx, eax
  
  iterateChar:
      cmp     byte [eax], 0
      jz      finalize
      inc     eax
      jmp     iterateChar
  
  finalize:
      sub     eax, ebx
      pop     ebx
      ret
  
  
  ;------------------------------------------
  ; void breakLine()
  ; Break a line - linefeed
  breakLine:
          push    eax     ; push eax on the stack
      mov eax, 0x0a   ; move linefeed into eax - 0x0a = 0Ah
  
      push    eax     ; linefeed on stack to get adress
      mov     eax, esp    ; move adress of current pointer into eax
      call    printString
      pop eax
      pop     eax
      ret         ; return
  
  
  ;------------------------------------------
  ; void exit()
  ; Exit program and restore resources
  quit:
      mov eax, 1      ; invoke SYS_EXIT (kernel opcode 1)
      mov ebx, 0      ; return 0 status on exit - 'No Errors' 
      int 0x80        ; 0x80=80h
      ret
  </code></pre>
  
  <p>and the print-functions in print.asm:</p>
  
  <pre><code>;------------------------------------------
  ; void printInteger (Integer number)
  ; Integer printing function (itoa)
  printInteger:
      push    eax             ; preserve eax on the stack to be restored after function runs
      push    ecx             ; preserve ecx on the stack to be restored after function runs
      push    edx             ; preserve edx on the stack to be restored after function runs
      push    esi             ; preserve esi on the stack to be restored after function runs
      mov     ecx, 0          ; counter of how many bytes we need to print in the end
  
  divideLoop:
      inc     ecx             ; count each byte to print - number of characters
      mov     edx, 0          ; empty edx
      mov     esi, 10         ; mov 10 into esi
      idiv    esi             ; divide eax by esi
      add     edx, 48         ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction
      push    edx             ; push edx (string representation of an intger) onto the stack
      cmp     eax, 0          ; can the integer be divided anymore?
      jnz     divideLoop      ; jump if not zero to the label divideLoop
  
  printLoop:
      dec     ecx             ; count down each byte that we put on the stack
      mov     eax, esp        ; mov the stack pointer into eax for printing
      call    printString     ; call our string print function
      pop     eax             ; remove last character from the stack to move esp forward
      cmp     ecx, 0          ; have we printed all bytes we pushed onto the stack?
      jnz     printLoop       ; jump is not zero to the label printLoop
  
      pop     esi             ; restore esi from the value we pushed onto the stack at the start
      pop     edx             ; restore edx from the value we pushed onto the stack at the start
      pop     ecx             ; restore ecx from the value we pushed onto the stack at the start
      pop     eax             ; restore eax from the value we pushed onto the stack at the start
      ret
  
  ;------------------------------------------
  ; void printString(String message)
  ; String printing function
  printString:
      push    edx
      push    ecx
      push    ebx
      push    eax
  
      call    lenString
  
      mov edx, eax    ; nbytes - number of bytes to write (len), one for each letter plus the zero terminating byte  
      pop eax
  
      mov ecx, eax    ; buffer - move the memory address of our message string into ecx                         
      mov     ebx, 1      ; fd - filedescriptor, write to the STDOUT file                                    
      mov     eax, 4      ; invoke SYS_WRITE (with fd, buf, nbytes / kernel opcode 4)
  
      int 0x80        ; prozessor interupt 0x80 jump to system call, stack clean, 0x80=80h
  
      pop ebx
      pop ecx
      pop edx
      ret
  </code></pre>
  
  <p>I appreciate any tipps,</p>
  
  <p>kind regards</p>