summaryrefslogtreecommitdiffstats
path: root/dec-to-ascii.asm
diff options
context:
space:
mode:
Diffstat (limited to 'dec-to-ascii.asm')
-rw-r--r--dec-to-ascii.asm126
1 files changed, 126 insertions, 0 deletions
diff --git a/dec-to-ascii.asm b/dec-to-ascii.asm
new file mode 100644
index 0000000..d40faf7
--- /dev/null
+++ b/dec-to-ascii.asm
@@ -0,0 +1,126 @@
+; Version : 1.1
+; Last update : 25/5/2019
+; Description : This program converts ASCII digits into the ASCII value. e.g. 65 --> 'Digit: A'
+; Know issues : Due to how 4 bytes are read at a time, only newline buffered terminal input works. Converting numbers from a file does not work.
+; Licence : GPLv3
+
+section .data
+Output: db 'Digit: !',0xA;'!' is overwritten
+Outputlen: equ $-Output
+Buffer: db 0,0,0,0 ;input is read into here
+
+section .text
+ global _start
+
+_start:
+xor edi,edi ;file descriptor = stdin = 0
+lea rsi,[Buffer] ;Address to read into
+mov edx,4 ;number of bytes to read
+xor eax,eax ;SYSCALL number for reading from STDIN
+syscall
+
+test eax,eax
+jz exit ;exit on EOF (syscall returned 0)
+
+cmp eax,2
+je one ;one inputted digit
+
+cmp eax,3
+je two ;two inputted digits
+
+cmp eax,4
+je three ;three inputted digits
+
+jmp _start ;reset on invalid input
+
+one: xor eax,eax ;needs to be zeroed
+mov al,byte[Buffer] ;mov digit into rax,
+
+;;check that the input values are valid and reset if not
+cmp eax,'0'
+jb _start
+cmp eax,'9'
+ja _start
+
+sub eax,'0' ;convert ASCII digit into number
+mov byte[Output+7],al ;mov value to output string
+jmp print
+
+two:
+xor eax, eax ;needs to be zeroed
+xor ecx,ecx ;needs to be zeroed
+mov al,byte[Buffer+1] ;mov second digit into rax
+mov cl,byte[Buffer] ;mov first digit into rcx
+
+;;check that the input values are valid and reset if not
+cmp eax,'0'
+jb _start
+cmp eax,'9'
+ja _start
+
+cmp ecx,'0'
+jb _start
+cmp ecx,'9'
+ja _start
+
+;;multiply rcx by 10
+lea ecx,[ecx+ecx*4] ;*5
+add ecx,ecx ;*2
+
+add eax,ecx ;add first and second digit together
+
+sub eax,16 ;the result is 16 above the correct ASCII char, so 16 is subtracted
+
+mov byte[Output+7],al ;mov value into output string
+jmp print
+
+three:
+xor eax,eax ;needs to be zeroed
+xor ecx,ecx ;needs to be zeroed
+xor edx,edx ;needs to be zeroed
+mov al,byte[Buffer+2] ;mov third digit into rax
+mov cl,byte[Buffer+1] ;mov second digit into rcx
+mov dl,byte[Buffer] ;mov first digit into rdx
+
+;;check that the input values are valid and reset if not
+cmp eax,'0'
+jb _start
+cmp eax,'9'
+ja _start
+
+cmp ecx,'0'
+jb _start
+cmp ecx,'9'
+ja _start
+
+cmp edx,'1'
+jne _start ;only '1' as the first digit is valid
+
+
+;;multiply rcx by 10
+lea ecx,[ecx+ecx*4] ;*5
+add ecx,ecx ;*2
+
+add eax,ecx ;add first and second digit together
+
+;;assume first char can only be '1', and cut off a lot of extended ASCII
+add eax,100 ;add 100 to rax
+
+sub eax,16 ;the result is 16 above the correct ASCII char, so 16 is subtracted
+
+mov byte[Output+7],al ;mov rax into Output
+;;fall through
+
+print:
+mov eax,1 ;sys_write
+mov edi,1 ;fd = STDOUT_FILENO
+lea rsi,[Output] ;string to write
+mov edx,Outputlen ;length of string to write
+syscall
+
+jmp _start ;read the next number
+
+exit:
+xor edi,edi ;set exit status = 0
+mov eax,60 ;SYSCALL number for EXIT
+syscall