-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathexp.asm
215 lines (200 loc) · 3.72 KB
/
exp.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
205
206
207
208
209
210
211
212
213
214
215
; b^e | 0 <= (b, e) <= 9
org 0x7c00
jmp 0x0000:main
data:
string times 11 db 0
lower times 11 db 0
upper times 11 db 0
putchar:
mov ah, 0x0e
int 10h
ret
getchar:
mov ah, 0x00
int 16h
ret
delchar:
mov al, 0x08 ; backspace
call putchar
mov al, ' '
call putchar
mov al, 0x08 ; backspace
call putchar
ret
endl:
mov al, 0x0a ; line feed
call putchar
mov al, 0x0d ; carriage return
call putchar
ret
prints: ; mov si, string
.loop:
lodsb ; bota character em al
cmp al, 0
je .endloop
call putchar
jmp .loop
.endloop:
ret
reverse: ; mov si, string
mov di, si
xor cx, cx ; zerar contador
.loop1: ; botar string na stack
lodsb
cmp al, 0
je .endloop1
inc cl
push ax
jmp .loop1
.endloop1:
.loop2: ; remover string da stack
pop ax
stosb
loop .loop2
ret
tostring: ; mov ax, int / mov di, string
push di
.loop1:
cmp ax, 0
je .endloop1
xor dx, dx
mov bx, 10
div bx ; ax = 9999 -> ax = 999, dx = 9
xchg ax, dx ; swap ax, dx
add ax, 48 ; 9 + '0' = '9'
stosb
xchg ax, dx
jmp .loop1
.endloop1:
pop si
cmp si, di
jne .done
mov al, 48
stosb
.done:
mov al, 0
stosb
call reverse
ret
gets: ; mov di, string
xor cx, cx ; zerar contador
.loop1:
call getchar
cmp al, 0x08 ; backspace
je .backspace
cmp al, 0x0d ; carriage return
je .done
cmp cl, 10 ; string limit checker
je .loop1
stosb
inc cl
call putchar
jmp .loop1
.backspace:
cmp cl, 0 ; is empty?
je .loop1
dec di
dec cl
mov byte[di], 0
call delchar
jmp .loop1
.done:
mov al, 0
stosb
call endl
ret
stoi: ; mov si, string
xor cx, cx
xor ax, ax
.loop1:
push ax
lodsb
mov cl, al
pop ax
cmp cl, 0 ; check EOF(NULL)
je .endloop1
sub cl, 48 ; '9'-'0' = 9
mov bx, 10
mul bx ; 999*10 = 9990
add ax, cx ; 9990+9 = 9999
jmp .loop1
.endloop1:
ret
main:
xor ax, ax
mov ds, ax
mov es, ax
mov di, string
call gets
mov si, string
call stoi
push ax ; save base
mov di, string
call gets
mov si, string
call stoi
push ax ; save expoent
mov ax, 1
pop cx ; get expoent
pop bx ; get base
cmp cx, 0
je .endexp
; b^e = b^(e-5) * (b^5), evitar overflow
; exemplo : 9^9 = 9^(9-5) * 9^(5) = 6561 * 59049, ambos os fatores menores que 2 ^ 16
.loop1:
cmp cx, 5
jle .endloop1
mul bx
dec cx
jmp .loop1
.endloop1:
push ax
mov ax, 1
.loop2:
mul bx
loop .loop2
pop bx
mul bx ; obter b^e, fazendo a multiplicacao de b^(e-5) * (b^5)
.endexp:
mov bx, 10000
div bx ; separar o numero em duas partes, a lower contém os 4 digitos menos significativos
cmp ax, 0 ; verificar se existe upper
xchg ax, dx ; ax = lower, dx = upper
je .no_upper
.with_upper:
xchg ax, dx
push dx
; printar upper
mov di, upper
call tostring
mov si, upper
call prints
; printar lower
pop ax
mov cx, 4
.loop3:
xor dx, dx
mov bx, 10
div bx
xchg ax, dx
add al, 48
push ax
xchg ax, dx
loop .loop3
mov cx, 4
.loop4:
pop ax
call putchar
loop .loop4
call endl
jmp end
.no_upper:
; printar lower, caso não haja upper
mov di, lower
call tostring
mov si, lower
call prints
call endl
end:
times 510-($-$$) db 0
dw 0xaa55