-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalculator.asm
204 lines (163 loc) · 2.93 KB
/
calculator.asm
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
section .data
FEW_ARGS: db "Too Few Arguments", 0xA
INVALID_OPERATOR: db "Invalid Operator", 0xA
INVALID_OPERAND: db "Invalid Operand", 0XA
BYTE_BUFFER: times 10 db 0 ;
section .text
global _start
_start:
pop rdx
cmp rdx, 4
jne few_args
add rsp, 8
pop rsi
cmp byte[rsi], 0x2A ;If operator is '*' then goto block multiplication , can be used only if escaped manually while giving input
je multiplication
cmp byte[rsi], 0x78 ;If operator is 'x' then goto block multiplication , cause you know some shells or every have '*' as wildcard
je multiplication
cmp byte[rsi], 0x2B ;If operator is '+' then goto block addition
je addition
cmp byte[rsi], 0x2D ;If operator is '-' then goto block subtraction
je subtraction
cmp byte[rsi], 0x2F ;If operator is '/' then goto block division
je division
cmp byte[rsi], 0x25 ;If operator is '%' then goto block modulo
je modulo
;If <operator> does not match to any case then goto block invalid_operator
jmp invalid_operator
addition:
pop rsi
call char_to_int
mov r10, rax
pop rsi
call char_to_int
add rax, r10
jmp print_result
subtraction:
pop rsi
call char_to_int
mov r10, rax
pop rsi
call char_to_int
sub r10, rax
mov rax, r10
jmp print_result
multiplication:
pop rsi
call char_to_int
mov r10, rax
pop rsi
call char_to_int
mul r10
jmp print_result
division:
pop rsi
call char_to_int
mov r10, rax
pop rsi
call char_to_int
mov r11, rax
mov rax, r10
mov rdx, 0
div r11
jmp print_result
modulo:
pop rsi
call char_to_int
mov r10, rax
pop rsi
call char_to_int
mov r11, rax
mov rax, r10
mov rdx, 0
div r11
mov rax, rdx
jmp print_result
print_result:
call int_to_char
mov rax, 1
mov rdi, 1
mov rsi, r9
mov rdx, r11
syscall
jmp exit
few_args:
mov rdi, FEW_ARGS
call print_error
invalid_operator:
mov rdi, INVALID_OPERATOR
call print_error
invalid_operand:
mov rdi, INVALID_OPERAND
call print_error
print_error:
push rdi
call strlen ;calculate the length of rdi (error message)
mov rdi, 2
pop rsi
mov rdx, rax ;result of strlen
mov rax, 1
syscall
call error_exit
ret
strlen:
xor rax, rax ;store zero in rax
.strlen_loop:
cmp BYTE [rdi + rax], 0xA
je .strlen_break
inc rax
jmp .strlen_loop
.strlen_break:
inc rax
ret
char_to_int:
xor ax, ax
xor cx, cx
mov bx, 10
.loop_block:
mov cl, [rsi]
cmp cl, byte 0
je .return_block
cmp cl, 0x30
jl invalid_operand
cmp cl, 0x39
jg invalid_operand
sub cl, 48
mul bx
add ax, cx
inc rsi
jmp .loop_block
.return_block:
ret
int_to_char:
mov rbx, 10
mov r9, BYTE_BUFFER+10
mov [r9], byte 0
dec r9
mov [r9], byte 0XA
dec r9
mov r11, 2
.loop_block:
mov rdx, 0
div rbx
cmp rax, 0
je .return_block
add dl, 48
mov [r9], dl
dec r9
inc r11
jmp .loop_block
.return_block:
add dl, 48
mov [r9], dl
dec r9
inc r11
ret
error_exit:
mov rax, 60
mov rdi, 1
syscall
exit:
mov rax, 60
mov rdi, 0
syscall