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
|