summaryrefslogtreecommitdiffstats
path: root/dec-to-ascii.asm
blob: d40faf7698af16e3f6811b4930059e10846218f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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