title: Assembly x86_64: Getting input integer from user and print it
body: <p>I'm trying to write a program that works in the following way:</p>
  
  <p>Get a number input by the user <code>-&gt;</code> divide it by, say, 2 <code>-&gt;</code> print the result (quotient).</p>
  
  <p>The <code>divide-by-the-number-2</code> part doesn't seem to represent too much difficulty, so preliminarily I wrote a program that gets an integer input by user and print that integer. </p>
  
  <p>That means I tried to write a program that convert the string integer of the user to a real integer and then convert it back to a string and print it.</p>
  
  <p>But after compiling I end up in a infinite loop (after hitting <code>Enter</code> nothing happens).</p>
  
  <p>I compile using the following commands:</p>
  
  <pre><code>nasm -f elf64 ascii.asm -o ascii.o
  
  ld ascii.o -o ascii
  
  ./ascii
  </code></pre>
  
  <p>In the code below the subroutine <code>_getInteger</code> is intended for converting from string to integer and the subroutine <code>_appendEOL</code> and <code>_loopDigit</code> for the whole convertion from integer to string. </p>
  
  <pre><code>section .bss
          ascii resb 16           ; holds user input
          intMemory resb 100      ; will hold the endline feed 
          intAddress resb 8       ; hold offset address from the intMemory
  
  section .data
          text db "It's not an integer", 10
          len equ $-text
  
  section .text
  
          global _start
  
  _start:
  
          call _getText
          call _toInteger
          call _appendEOL
  
  mov rax, 60
          mov rdi, 0
          syscall
  
  _getText:
          mov rax, 0
          mov rdi, 0
          mov rsi, ascii
          mov rdx, 16
          syscall
          ret
  
  _toInteger:
          mov rbx,10      ; for decimal scaling
          xor rax, rax    ; initializing result
          mov rcx, ascii  ; preparing for working with input
          movzx rdx, byte [rcx]   ; getting first byte (digit)
          inc rcx         ; for the next digit
  
          cmp rdx, '0'    ; if it's less than '0' is not a digit
          jb _invalid
  
          cmp rdx, '9'    ; if it's greater than '9' is not a digit
          ja _invalid
  
          sub rdx, '0'    ; getting decimal value
          mul rbx         ; rax = rax*10
          add rax, rdx    ; rax = rax + rdx
          jmp _toInteger  ; repeat
          ret
  
  _invalid:
          mov rax, 1
          mov rdi, 1
          mov rsi, text
          mov rdx, len
          syscall
          ret
  
  _appendEOL:
          ; getting EOL
          mov rcx, intMemory
          mov rbx, 10 ; EOL
          mov [rcx], rbx
          inc rcx
          mov [intAddress], rcx
  
  _loopDigit:
          xor rdx, rdx
          mov rbx, 10
          div rbx
          push rax
          add rdx, '0'
          mov rcx, [intAddress]
          mov [rcx], dl
          inc rcx
          mov [intAddress], rcx
          pop rax
          cmp rax, 0
          jne _loopDigit
  
  _printDigit:
          mov rcx, [intAddress]
  
          mov rax, 1
          mov rdi, 1
          mov rsi, rcx
          mov rdx, 1
          syscall
          mov rcx, [intAddress]
          dec rcx
          mov [intAddress], rcx
          cmp rcx, intMemory
          jge _printDigit
  
          ret
  </code></pre>