-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCalculator8051.asm
392 lines (339 loc) · 15.8 KB
/
Calculator8051.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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
ORG 00H
;CALCULADORA DE 8 BITS
; R0 É USADO PARA COMANDOS E DADOS NO LCD
; R1 GUARDA O PRIMEIRO NÚMERO
; R2 GUARDA A OPERAÇÃO
; R3 GUARDA O SEGUNDO NÚMERO
; PORTA P3 - ENTRADA DO TECLADO
; PORTA P2 - RESET + 2 PINOS DO LCD (E e RS))
; PORTA P1 - SAÍDA PARA O LCD
NOVONUM EQU P2.7 ; P2.7 IS HIGH WHEN WRITING SECOND NUMBER
NOVODIG EQU P2.6 ; P2.6 IS LOW ONLY WHEN WRITING FIRST DIGIT OF A NUMBER
RS EQU P2.1 ; RS ON LCD
RW EQU P2.2 ; RW ON LCD
;COMANDOS PARA PREPARAR LCD PARA ESCREVER NA TELA
MOV R0, #38H ;USA DUAS LINHAS E MATRIZ 5X7
ACALL COMMAND ;CHAMA A ROTINA PARA EXECUTAR O COMANDO NO LCD
MOV R0, #0EH ;DISPLAY LIGADO/CURSOR PISCANDO
ACALL COMMAND
MOV R0, #80H ;COLOCAR CURSOR NA PRIMEIRA LINHA
ACALL COMMAND
MOV R0, #01H ;LIMPA TELA DE EXIBIÇÃO
ACALL COMMAND
MOV R4, #00H ;ZERAR O REGISTRADOR R4
MOV P2, #00H ;ZERAR PORTA P2
MOV P3, #0FEH ;INÍCIO DO LDC COM L1 EM GROUND (LINHA 1 ATIVA)
MOV R3, #00H ;ZERAR O REGISTRADOR R3
MOV R1, #00H ;ZERAR O REGISTRADOR R1
MOV R2, #'+' ;CASO SE DIGITE SÓ IGUAL OU SÓ UM NÚMERO E IGUAL
L1:
JNB P3.0, C1 ;SALTA PARA C1 SE FOR 0 (SEMPRE COMEÇA EM 0)
JNB P3.1, C2 ;SALTA PARA C2 SE FOR 0
JNB P3.2, C3 ;SALTA PARA C3 SE FOR 0
JNB P3.3, C4 ;SALTA PARA C4 SE FOR 0
SJMP L1 ;RETORNA À CHECAGEM DAS LINHAS
C1: JNB P3.4, SALTO_BOT_ON ;SALTA SE O BOTÃO ON FOR APERTADO
JNB P3.5, SALTO_BOT_ZERO ;SALTA SE O BOTÃO '0' FOR APERTADO
JNB P3.6, SALTO_BOT_IGUAL ;SALTA SE O BOTÃO '=' FOR APERTADO
JNB P3.7, SALTO_BOT_MAIS ;SALTA SE O BOTÃO '+' FOR APERTADO
SETB P3.0 ;DESATIVA LINHA 1
CLR P3.1 ;ATIVA LINHA 2
SJMP L1 ;RETORNA À CHECAGEM DAS LINHAS
C2: JNB P3.4, SALTO_BOT_1 ;SALTA SE O BOTÃO '1' FOR APERTADO
JNB P3.5, SALTO_BOT_2 ;SALTA SE O BOTÃO '2' FOR APERTADO
JNB P3.6, SALTO_BOT_3 ;SALTA SE O BOTÃO '3' FOR APERTADO
JNB P3.7, SALTO_BOT_MENOS ;SALTA SE O BOTÃO '-' FOR APERTADO
SETB P3.1 ;DESATIVA LINHA 2
CLR P3.2 ;ATIVA LINHA 3
SJMP L1 ;RETORNA À CHECAGEM DAS LINHAS
C3: JNB P3.4, SALTO_BOT_4 ;SALTA SE O BOTÃO '4' FOR APERTADO
JNB P3.5, SALTO_BOT_5 ;SALTA SE O BOTÃO '5' FOR APERTADO
JNB P3.6, SALTO_BOT_6 ;SALTA SE O BOTÃO '6' FOR APERTADO
JNB P3.7, SALTO_BOT_VEZES ;SALTA SE O BOTÃO 'x' FOR APERTADO
SETB P3.2 ;DESATIVA LINHA 3
CLR P3.3 ;ATIVA LINHA 4
SJMP L1 ;RETORNA À CHECAGEM DAS LINHAS
C4: JNB P3.4, SALTO_BOT_7 ;SALTA SE O BOTÃO '7' FOR APERTADO
JNB P3.5, SALTO_BOT_8 ;SALTA SE O BOTÃO '8' FOR APERTADO
JNB P3.6, SALTO_BOT_9 ;SALTA SE O BOTÃO '9' FOR APERTADO
JNB P3.7, SALTO_BOT_DIVISAO ;SALTA SE O BOTÃO '/' FOR APERTADO
SETB P3.3 ;DESATIVA LINHA 4
CLR P3.0 ;ATIVA LINHA 1
LJMP L1 ;RETORNA À CHECAGEM DAS LINHAS (LJMP SALTO GRANDE)
SALTO_BOT_ON: LJMP BOT_ON
SALTO_BOT_ZERO: LJMP BOT_ZERO
SALTO_BOT_1: LJMP BOT_1
SALTO_BOT_2: LJMP BOT_2
SALTO_BOT_3: LJMP BOT_3
SALTO_BOT_4: LJMP BOT_4
SALTO_BOT_5: LJMP BOT_5
SALTO_BOT_6: LJMP BOT_6
SALTO_BOT_7: LJMP BOT_7
SALTO_BOT_8: LJMP BOT_8
SALTO_BOT_9: LJMP BOT_9
SALTO_BOT_MAIS: LJMP BOT_MAIS
SALTO_BOT_MENOS: LJMP BOT_MENOS
SALTO_BOT_VEZES: LJMP BOT_VEZES
SALTO_BOT_DIVISAO: LJMP BOT_DIVISAO
SALTO_BOT_IGUAL: LJMP BOT_IGUAL
BOT_ON: SETB P2.0 ;ATIVAR O RESET
LJMP L1
BOT_ZERO: MOV R0, #'0' ;MOVER O CARACTERE '0' PARA R0
ACALL NUMERO ;GUARDA O NÚMERO
ACALL DISPLAY ;IMPRIME O CARACTERE NO LCD
LJMP L1
BOT_IGUAL: MOV R0, #'=' ;MOVER O CARACTERE '=' PARA R0
ACALL DISPLAY ;IMPRIME NA TELA
ACALL RESULTADO ;REALIZA A OPERAÇÃO
LJMP L1
BOT_MAIS: MOV R0, #'+' ;MOVER O CARACTERE '+' PARA R0
ACALL OPERACAO ;GUARDA A OPERAÇÃO EM R2
ACALL DISPLAY ;IMPRIME NA TELA
LJMP L1
BOT_1: MOV R0, #'1' ;MOVER O CARACTERE '1' PARA R0
ACALL NUMERO ;GUARDA O NÚMERO
ACALL DISPLAY ;IMPRIME NA TELA
LJMP L1
BOT_2: MOV R0, #'2' ;MOVER O CARACTERE '2' PARA R0
ACALL NUMERO ;GUARDA O NÚMERO
ACALL DISPLAY ;IMPRIME NA TELA
LJMP L1
BOT_3: MOV R0, #'3' ;MOVER O CARACTERE '3' PARA R0
ACALL NUMERO ;GUARDA O NÚMERO
ACALL DISPLAY ;IMPRIME NA TELA
LJMP L1
BOT_MENOS: MOV R0, #'-' ;MOVER O CARACTERE '-' PARA R0
ACALL OPERACAO ;GUARDA A OPERAÇÃO EM R2
ACALL DISPLAY ;IMPRIME NA TELA
LJMP L1
BOT_4: MOV R0, #'4' ;MOVER O CARACTERE '4' PARA R0
ACALL NUMERO ;GUARDA O NÚMERO
ACALL DISPLAY ;IMPRIME NA TELA
LJMP L1
BOT_5: MOV R0, #'5' ;MOVER O CARACTERE '5' PARA R0
ACALL NUMERO ;GUARDA O NÚMERO
ACALL DISPLAY ;IMPRIME NA TELA
LJMP L1
BOT_6: MOV R0, #'6' ;MOVER O CARACTERE '6' PARA R0
ACALL NUMERO ;GUARDA O NÚMERO
ACALL DISPLAY ;IMPRIME NA TELA
LJMP L1
BOT_VEZES: MOV R0, #'*' ;MOVER O CARACTERE '*' PARA R0
ACALL OPERACAO ;GUARDA A OPERAÇÃO EM R2
ACALL DISPLAY ;IMPRIME NA TELA
LJMP L1
BOT_7: MOV R0, #'7' ;MOVER O CARACTERE '7' PARA R0
ACALL NUMERO ;GUARDA O NÚMERO
ACALL DISPLAY ;IMPRIME NA TELA
LJMP L1
BOT_8: MOV R0, #'8' ;MOVER O CARACTERE '8' PARA R0
ACALL NUMERO ;GUARDA O NÚMERO
ACALL DISPLAY ;IMPRIME NA TELA
LJMP L1
BOT_9: MOV R0, #'9' ;MOVER O CARACTERE '9' PARA R0
ACALL NUMERO ;GUARDA O NÚMERO
ACALL DISPLAY ;IMPRIME NA TELA
LJMP L1
BOT_DIVISAO: MOV R0, #'/' ;MOVER O CARACTERE '/' PARA R0
ACALL OPERACAO ;GUARDA A OPERAÇÃO EM R2
ACALL DISPLAY ;IMPRIME NA TELA
LJMP L1
DISPLAY:
MOV P1, R0 ;MOVE O CARACTERE PARA A SAÍDA (P1)
SETB RS ;COLOCA RS (REGISTER SELECT) NO MODO DE DADOS
SETB RW ;LIBERA PERMISSÃO DE LEITURA/ESCRITA NO LCD (NÍVEL ALTO)
CLR RW
ACALL DELAY ;CHAMA UM DELAY DE 0.25s (IMPEDIR QUE IMPRIMA VÁRIAS VEZES)
RET
COMMAND:
MOV P1, R0 ;MOVE O COMANDO PARA A PORTA DE SAÍDA - ENTRADA DO LCD
CLR RS ;COLOCA RS (REGISTER SELECT) NO MODO DE COMANDO
SETB RW ;LIBERA PERMISSÃO DE LEITURA/ESCRITA NO LCD (NÍVEL ALTO)
CLR RW
ACALL DELAY ;CHAMA UM DELAY DE 0.25s
RET
NUMERO:
JB NOVONUM, SEGUNDONUM ;SALTA SE FOR O SEGUNDO NÚMERO
JB NOVODIG, NOVODIGITO ;SALTA SE NÃO FOR O PRIMEIRO DÍGITO DO PRIMEIRO NÚMERO
MOV A, R0 ;MOVE O CARACTERE PARA O ACUMULADOR
SUBB A, #30H ;TRANFORMA ESSE CARACTERE NO EQUIVALENTE NUMÉRICO
MOV R1, A ;GUARDA ESSE NÚMERO NO REGISTRADOR R1
SETB NOVODIG ;SETAR PINO NOVODIG => PRIMEIRO DÍGITO DO PRIMEIRO NÚMERO FOI GUARDADO
RET
NOVODIGITO:
MOV A, R0 ;MOVE O NOVO CARACTERE PARA O ACUMULADOR
MOV B, #10D ;MOVE A CONSTANTE 10 PARA O ACUMULADOR AUXILIAR
SUBB A, #30H ;TRANFORMA ESSE CARACTERE NO EQUIVALENTE NUMÉRICO
MOV R7, A ;MOVE RESULTADO PARA O REGISTRADOR R7
MOV A, R1 ;MOVE O NÚMERO ATUAL (PRIMEIRO NÚMERO) PARA O ACUMULADOR
MUL AB ;MULTIPLICA O NÚMERO ATUAL POR 10
MOV R6, B ;GUARDA A PARTE MAIS SIGNIFICATIVA EM R6
CJNE R6, #00H, SALTO_ESTOURO ;CASO HAJA ALGUM VALOR EM B OU R6, EXCEDEU 8 BITS
ADD A, R7 ;SE NÃO EXCEDEU, SOMA O (NÚMERO ATUAL X 10) COM O NOVO DÍGITO
JC SALTO_ESTOURO ;SE O CARRY FOR 1, A SOMA EXCECEU 8 BITS (SALTA PARA LABEL ESTOURO)
MOV R1, A ;MOVE RESULTADO DO PRIMEIRO NÚMERO PARA O REGISTRADOR R1
SETB NOVODIG ;SETAR PINO NOVODIG => NOVO NÚMERO FOI GUARDADO
RET
SEGUNDONUM:
JB NOVODIG, NOVODIGITO2 ;SALTA SE NÃO FOR O PRIMEIRO DÍGITO DO SEGUNDO NÚMERO
MOV A, R0 ;MOVE O CARACTERE PARA O ACUMULADOR
SUBB A, #30H ;TRANFORMA ESSE CARACTERE NO EQUIVALENTE NUMÉRICO
MOV R3, A ;GUARDA ESSE NÚMERO NO REGISTRADOR R3
SETB NOVODIG ;SETAR PINO NOVODIG => PRIMEIRO DÍGITO DO SEGUNDO NÚMERO FOI GUARDADO
RET ;RETORNA
NOVODIGITO2:
MOV A, R0 ;MOVE O NOVO CARACTERE PARA O ACUMULADOR
MOV B, #10D ;MOVE A CONSTANTE 10 PARA O ACUMULADOR AUXILIAR
SUBB A, #30H ;TRANFORMA ESSE CARACTERE NO EQUIVALENTE NUMÉRICO
MOV R7, A ;MOVE RESULTADO PARA O REGISTRADOR R7
MOV A, R3 ;MOVE O NÚMERO ATUAL (SEGUNDO NÚMERO) PARA O ACUMULADOR
MUL AB ;MULTIPLICA O NÚMERO ATUAL POR 10
MOV R6, B ;GUARDA A PARTE MAIS SIGNIFICATIVA EM R6
CJNE R6, #00H, SALTO_ESTOURO ;CASO HAJA ALGUM VALOR EM B OU R6, EXCEDEU 8 BITS
ADD A, R7 ;SE NÃO EXCEDEU, SOMA O (NÚMERO ATUAL X 10) COM O NOVO DÍGITO
JC SALTO_ESTOURO ;SE O CARRY FOR 1, A SOMA EXCECEU 8 BITS (SALTA PARA LABEL ESTOURO)
MOV R3, A ;MOVE RESULTADO DO SEGUNDO NÚMERO PARA O REGISTRADOR R1
SETB NOVODIG ;SETAR PINO NOVODIG => NOVO NÚMERO FOI GUARDADO
RET
OPERACAO:
SETB NOVONUM ;SETA NOVONUM, INDICANDO QUE PRÓXIMO DÍGITO É DO SEGUNDO NÚMERO
CLR NOVODIG ;LIMPA NOVODIG, INDICANDO QUE O PRÓXIMO DÍGITO SERÁ O PRIMEIRO
MOV A, R0 ;MOVE O CARACTERE DA OPERAÇÃO PARA O ACUMULADOR
MOV R2, A ;MOVE O CARACTERE DA OPERAÇÃO PARA R2
RET
RESULTADO:
CJNE R2, #'+', SUBTRACAO ;VERIFICA SE A OPERAÇÃO É SOMA
MOV A, R1 ;MOVER O PRIMEIRO NÚMERO PARA O ACUMULADOR
CLR C ;LIMPA O CARRY
ADD A, R3 ;SOMA O PRIMEIRO NÚMERO COM O SEGUNDO NÚMERO
JC SALTO_ESTOURO ;SE O CARRY FOR 1, A SOMA EXCECEU 8BITS (SALTA PARA LABEL ESTOURO)
MOV R5, #0H ;MOVE 0 PARA O REGISTRADOR R5 (NÃO TEM RESTO - NÃO DECIMAL)
MOV R4, A ;GUARDA O RESULTADO DA SOMA EM R4
LJMP IMPRIMIR ;SALTA PARA A LABEL IMPRIMIR
SUBTRACAO:
CJNE R2, #'-', MULTIPLICACAO ;VERIFICA SE A OPERAÇÃO É SUBTRAÇÃO
MOV A, R1 ;MOVER O PRIMEIRO NÚMERO PARA O ACUMULADOR
CLR C ;LIMPA O CARRY
SUBB A, R3 ;SUBTRAI O SEGUNDO NÚMERO DO PRIMEIRO NÚMERO
JC SALTO_ESTOURO ;SE O CARRY FOR 1, A SOMA EXCECEU 8BITS (SALTA PARA LABEL ESTOURO)
MOV R5, #0H ;MOVE 0 PARA O REGISTRADOR R5 (NÃO TEM RESTO - NÃO DECIMAL)
MOV R4, A ;GUARDA O RESULTADO DA SOMA EM R4
LJMP IMPRIMIR ;SALTA PARA A LABEL IMPRIMIR
MULTIPLICACAO:
CJNE R2, #'*', DIVISAO ;VERIFICA SE A OPERAÇÃO É MULTIPLICAÇÃO
MOV A, R1 ;MOVER O PRIMEIRO NÚMERO PARA O ACUMULADOR
MOV B, R3 ;MOVER O SEGUNDO NÚMERO PARA O ACUMULADOR AUXILIAR
MUL AB ;MULTIPLICAR O PRIMEIRO NÚMERO PELO SEGUNDO NÚMERO
MOV R7, B ;GUARDA A PARTE MAIS SIGNIFICATIVA EM R7
CJNE R7, #0H, ESTOURO ;CASO HAJA ALGUM VALOR EM B OU R7, EXCEDEU 8 BITS
MOV R5, #0H ;MOVE 0 PARA O REGISTRADOR R5 (NÃO TEM RESTO - NÃO DECIMAL)
MOV R4, A ;GUARDA O RESULTADO DA SOMA EM R4
LJMP IMPRIMIR ;SALTA PARA A LABEL IMPRIMIR
DIVISAO: ;OPERAÇÃO DE DIVISÃO
MOV A, R1 ;MOVER O PRIMEIRO NÚMERO PARA O ACUMULADOR
MOV B, R3 ;MOVER O SEGUNDO NÚMERO PARA O ACUMULADOR AUXILIAR
DIV AB ;DIVIDIR O PRIMEIRO NÚMERO PELO SEGUNDO NÚMERO
MOV R4, A ;GUARDA O RESULTADO DA SOMA EM R4
MOV R5, B ;GUARDA A PARTE MAIS SIGNIFICATIVA EM R5
LJMP IMPRIMIR ;SALTA PARA A LABEL IMPRIMIR
SALTO_ESTOURO: LJMP ESTOURO ;LABEL COM SALTO LONGO PARA LABEL ESTOURO
IMPRIMIR:
CJNE R3, #0D, NORMAL ;SALTA SE O SEGUNDO NÚMERO FOR DIFERENTE DE ZERO
CJNE R2, #'/', NORMAL ;SALTA SE A OPERAÇÃO NÃO FOR DIVISÃO
MOV R0, #0C0H ;COLOCAR CURSOR NA SEGUNDA LINHA
ACALL COMMAND ;CHAMA A ROTINA PARA EXECUTAR COMANDOS NO LCD
MOV DPTR, #MSGERRO ;MOVE ENDEREÇO DO VETOR PARA O REGISTRADOR DPTR (DIVISÃO POR ZERO)
CLR C ;LIMPA O CARRY
MOV R7, #0D ;MOVE 0 PARA O REGISTRADOR R7
PROX: MOV A, R7 ;MOVE O CONTEÚDO DE R7 PARA O ACUMULADOR
MOVC A, @A+DPTR ;MOVE O CONTEÚDO ENDEREÇADO POR A+DPTR PARA A
MOV R0, A ;MOVE RESULTADO PARA O REGISTRADOR R0
ACALL DISPLAY ;IMPRIME NO LCD
INC R7 ;SE NÃO FOR 0, INCREMENTA R7
JNZ PROX ;SE NÃO FOR ZERO, PULA PARA LABEL PROX
RET
NORMAL: MOV R7, #100D ;MOVE A CONSTANTE 100 PARA O REGISTRADOR R7
CLR C ;LIMPA O CARRY (PARA NÃO INFERFERIR NA SUBTRAÇÃO)
SUBB A, R7 ;SUBTRAIR 100 DO RESULTADO
JC MENOR100 ;SE O CARRY FOR 1, O RESULTADO É < 100 - SALTA PARA LABEL MENOR100
MOV A, R4 ;MOVE RESULTADO PARA O ACUMULADOR NOVAMENTE (NÚMERO DE 3 DÍGITOS)
MOV B, R7 ;MOVE A CONSTANTE 100 PARA O REGISTRADOR ACUMULADOR AUXILIAR
DIV AB ;DIVIDE O RESULTADO POR 100 PARA PEGAR O TERCEIRO DÍGITO
ADD A, #30H ;TRANFORMA O NÚMERO NO CARACTERE EQUIVALENTE
MOV R0, A ;MOVE O CARACTERE EQUIVALENTE PARA O RESGISTRADOR R0 (CENTENA)
ACALL DISPLAY ;CHAMA A LABEL PARA IMPRIMIR O CARACTERE NA TELA DO LCD (CENTENA)
MOV R4, B ;MOVE O RESTO DA DIVISÃO POR 100 PARA R4
MOV A, B ;MOVE O RESTO DA DIVISÃO POR 100 PARA O ACUMULADOR
MOV R7, #10D ;MOVE A CONSTANTE 10 PARA O REGISTRADOR R7
MOV B, R7 ;MOVE A CONSTANTE 10 PARA O REGISTRADOR ACUMULADOR AUXILIAR
DIV AB ;DIVIDE O RESTO DA DIVISÃO POR 100, AGORA POR 10
ADD A, #30H ;TRANFORMA O NÚMERO NO CARACTERE EQUIVALENTE
MOV R0, A ;MOVE O CARACTERE EQUIVALENTE PARA O RESGISTRADOR R0 (DEZENA)
ACALL DISPLAY ;CHAMA A LABEL PARA IMPRIMIR O CARACTERE NA TELA DO LCD (DEZENA)
MOV A, B ;MOVE O RESTO DA DIVISÃO POR 10 PARA O ACUMULADOR
ADD A, #30H ;TRANFORMA O NÚMERO NO CARACTERE EQUIVALENTE
MOV R0, A ;MOVE O CARACTERE EQUIVALENTE PARA O RESGISTRADOR R0 (UNIDADE)
ACALL DISPLAY ;CHAMA A LABEL PARA IMPRIMIR O CARACTERE NA TELA DO LCD (UNIDADE)
CJNE R5, #00H, DECIMAL ;SE O RESTO DA OPERAÇÃO DIVISÃO NÃO FOR 0, PULA PRA LABEL DECIMAL
RET
MENOR100: MOV R7, #10D ;MOVE A CONSTANTE 10 PARA O REGISTRADOR R7
CLR C ;LIMPA O CARRY (PARA NÃO INFERFERIR NA SUBTRAÇÃO)
MOV A, R4 ;MOVE RESULTADO PARA O ACUMULADOR
SUBB A, R7 ;SUBTRAIR 10 DO RESULTADO
JC MENOR10 ;SE O CARRY FOR 1, O RESULTADO É < 10 - SALTA PARA LABEL MENOR10
MOV A, R4 ;MOVE RESULTADO PARA O ACUMULADOR NOVAMENTE (NÚMERO DE 2 DÍGITOS)
MOV B, R7 ;MOVE A CONSTANTE 10 PARA O ACUMULADOR AUXILIAR
DIV AB ;DIVIDE O RESULTADO POR 10 PARA PEGAR O SEGUNDO DÍGITO
ADD A, #30H ;TRANFORMA O NÚMERO NO CARACTERE EQUIVALENTE
MOV R0, A ;MOVE O CARACTERE EQUIVALENTE PARA O RESGISTRADOR R0 (DEZENA)
ACALL DISPLAY ;CHAMA A LABEL PARA IMPRIMIR O CARACTERE NA TELA DO LCD (DEZENA)
MOV A, B ;MOVE O RESTO DA DIVISÃO POR 10 PARA O ACUMULADOR
ADD A, #30H ;TRANFORMA O NÚMERO NO CARACTERE EQUIVALENTE
MOV R0, A ;MOVE O CARACTERE EQUIVALENTE PARA O RESGISTRADOR R0 (UNIDADE)
ACALL DISPLAY ;CHAMA A LABEL PARA IMPRIMIR O CARACTERE NA TELA DO LCD (UNIDADE)
CJNE R5, #00H, DECIMAL ;SE O RESTO DA OPERAÇÃO DIVISÃO NÃO FOR 0, PULA PRA LABEL DECIMAL
RET
MENOR10:
MOV A, R4 ;MOVE RESULTADO PARA O ACUMULADOR
ADD A, #30H ;TRANFORMA O NÚMERO NO CARACTERE EQUIVALENTE
MOV R0, A ;MOVE O CARACTERE EQUIVALENTE PARA O RESGISTRADOR R0 (UNIDADE)
ACALL DISPLAY ;CHAMA A LABEL PARA IMPRIMIR O CARACTERE NA TELA DO LCD (UNIDADE)
CJNE R5, #00H, DECIMAL ;SE O RESTO DA OPERAÇÃO DIVISÃO NÃO FOR 0, PULA PRA LABEL DECIMAL
RET
ESTOURO:
MOV R0, #0C0H ;COLOCAR CURSOR NA SEGUNDA LINHA
ACALL COMMAND ;CHAMA A LABEL PARA EXECUTAR O COMANDO NO LCD
MOV DPTR, #MSGERRO2 ;MOVE ENDEREÇO DO VETOR PARA O REGISTRADOR DPTR
CLR C ;LIMPA O CARRY
MOV R7, #0D ;MOVE 0 PARA O REGISTRADOR R7
PROX2: MOV A, R7 ;MOVE O CONTEÚDO DE R7 PARA O ACUMULADOR
MOVC A, @A+DPTR ;MOVE O CONTEÚDO ENDEREÇADO POR A+DPTR para A
MOV R0, A ;MOVE RESULTADO PARA O REGISTRADOR R0
ACALL DISPLAY ;CHAMA A LABEL PARA IMPRIMIR O CARACTERE NA TELA DO LCD
JZ FIM ;QUANDO CHEGAR NO ZERO, PULA PARA LABEL FIM
INC R7 ;SE NÃO FOR 0, INCREMENTA R7
SJMP PROX2 ;SALTA PARA A LABEL PROX2 (LOOP PARA ESCREVER A MENSAGEM)
FIM:
RET
DECIMAL: MOV R0, #'.' ;MOVE CARACTERE '.' PARA O REGISTRADOR R0
ACALL DISPLAY ;CHAMA A LABEL PARA IMPRIMIR O CARACTERE NA TELA DO LCD
MOV A, R5 ;MOVE RESTO DA DIVISÃO PARA O ACUMULADOR
MOV B, #10D ;MOVE A CONSTANTE 10 PARA O ACUMULADOR AUXILIAR
MUL AB ;MULTIPLICA O RESTO DA DIVISÃO POR 10
MOV B, R3 ;MOVE O DIVISOR (SEGUNDO NÚMERO) PARA O ACUMULADOR AUXILIAR
DIV AB ;DIVIDE (RESTOX10) PELO SEGUNDO NÚMERO DE NOVO
ADD A, #30H ;TRANFORMA O NÚMERO NO CARACTERE EQUIVALENTE
MOV R0, A ;MOVE O CARACTERE EQUIVALENTE PARA O RESGISTRADOR R0 (PARTE DECIMAL)
ACALL DISPLAY ;CHAMA A LABEL PARA IMPRIMIR O CARACTERE NA TELA DO LCD (UNIDADE)
RET
DELAY: MOV 62, #2 ;APLICAR DELAY DE 0.25s
DELAY1: MOV 61, #250
DELAY2: MOV 60, #250
DJNZ 60, $
DJNZ 61, DELAY2
DJNZ 62, DELAY1
RET
;DB - DEFINE BYTE (INICIALIZA A MEMÓRIA)
MSGERRO: DB 'ERRO: DIV POR 0',0 ;VETOR DA MENSAGEM DE ERRO - DIVISÃO POR ZERO!
MSGERRO2: DB 'OVERFLOW!',0 ;VETOR DA MENSAGEM DE ERRO - EXCEDEU 8 BITS/NÚMERO NEGATIVO
END ;FIM DO PROGRAMA