I'm trying to write a program that works in the following way:
Get a number input by the user -> divide it by, say, 2 -> print the result (quotient).
The divide-by-the-number-2 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.
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.
But after compiling I end up in a infinite loop (after hitting Enter nothing happens).
I compile using the following commands:
nasm -f elf64 ascii.asm -o ascii.o
ld ascii.o -o ascii
./ascii
In the code below the subroutine _getInteger is intended for converting from string to integer and the subroutine _appendEOL and _loopDigit for the whole convertion from integer to string.
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