Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;============ calc by CyberBatman =========
- max_lin equ 4 ;tamanho maximo linha
- cr equ 0Dh ;carriage return
- lf equ 0Ah ;line feed
- stack segment stack
- dw 128 dup(?) ;128 words pilha
- topo_da_pilha label word ;delimita o começo da pilha
- stack ends
- dados segment
- area_leitura db max_lin ;numero maximo de caracteres
- tam_linha db ? ;numero caracteres lidos
- linha db max_lin dup(0) ;caracteres lidos
- numero_1 db 4 dup(0) ;primeiro numero
- numero_2 db 4 dup(0) ;segundo numero
- resultado db 4 dup(0) ;resultado da operacao
- tab_operadores db '+-*/' ;operadores validos
- n_operadores equ 4 ;numero operadores
- newl db cr,lf,'$'
- const_1 db 0,0,0,1h ;constante de valor 1
- tab_func dw offset soma ;contem endereco dos labels das subrotinas
- dw offset subtracao
- dw offset multiplicacao
- dw offset divisao
- apresentacao db cr,lf
- db 'Calculadora CyberBat 2014'
- db cr,lf
- db '$'
- comando1 db cr,lf,'CCB> Numero1 : ','$'
- comando2 db cr,lf,'CCB> Numero2 : ','$'
- comando3 db cr,lf,'CCB> Operando:','$'
- msg_resul db cr,lf,'Resultado:','$'
- dados ends
- codigo segment
- inicio:
- mov ax,stack ;define segmento de pilha no registrador
- mov ss,ax
- mov sp,offset topo_da_pilha
- mov ax,dados ;define segmento de dados no registrador
- mov ds,ax
- mov es,ax
- mov dx,offset apresentacao
- call print
- principal:
- ;=======leitura e preparação dos numeros=====
- mov dx,offset comando1
- call print
- mov dx,offset area_leitura
- call ler_linha
- mov dx,offset numero_1
- push dx
- call prepara_numero
- ; ** repete para o 2 numero **
- mov dx,offset comando2
- call print
- mov dx,offset area_leitura
- call ler_linha
- mov dx,offset numero_2
- push dx
- call prepara_numero
- ;obtém o operando
- mov dx,offset comando3
- call print
- mov dx,offset area_leitura
- call ler_linha
- ;prepara para chamar as operacoes (+,-,*,/)
- xor ax,ax
- mov al,linha
- mov di,offset tab_operadores
- mov cx,n_operadores
- repne scasb ;varre operadores em busca da posicao do operador informado
- sub di,offset tab_operadores
- dec di ;subtrai 1 para voltar a posicao
- sal di,1 ;*2 para ajustar para word
- mov si,offset resultado + 3
- mov cx,offset numero_1 + 3
- mov dx,offset numero_2 + 3
- push dx
- push cx
- push si
- call tab_func[di]
- add sp,6
- mov dx,offset msg_resul
- call print
- ;imprimir char por char do resultado
- mov cx,4h
- mov si,offset resultado
- imprimir_resp:
- lodsb
- add al,30h
- mov dl,al
- call printChar
- loop imprimir_resp
- xor ax,ax
- xor bx,bx
- xor cx,cx
- xor dx,dx
- hlt
- ;======== operacoes matematicas ========
- operacoes proc near
- soma:
- mov bp,sp
- mov bx,[bp+2]
- mov si,[bp+4]
- mov di,[bp+6]
- clc
- mov cx,4
- loop_soma:
- mov al,[si]
- adc al,[di]
- aaa
- mov [bx],al
- dec si
- dec di
- dec bx
- loop loop_soma
- ret
- subtracao:
- ;obtem o numero1 em ax
- mov al,0h
- mov di,offset numero_1
- mov cx,4
- repe scasb ;enquanto CX!=0 && ZF==1
- dec di
- sub di,offset numero_1 ;obtenho a quantidade de elementos
- mov bx,4h
- sub bx,di
- ;obtem numero2 em bx
- mov al,0h
- mov di,offset numero_2
- mov cx,4
- repe scasb
- dec di
- sub di,offset numero_2 ;obtenho a quantidade de elementos
- mov dx,4h
- sub dx,di
- ;verifica qual dos dois é maior
- cmp bx,dx
- jnc bx_maior ; bx>dx
- jc dx_maior ; dx>bx
- jz iguais ; bx=dx
- bx_maior:
- mov cx, bx
- jmp prossegue_sub
- dx_maior:
- mov cx, dx
- jmp prossegue_sub
- iguais:
- mov cx, bx
- jmp prossegue_sub
- prossegue_sub:
- mov bp,sp
- mov bx,[bp+2]
- mov si,[bp+4]
- mov di,[bp+6]
- clc
- loop_subtr:
- mov al,[si]
- sbb al,[di]
- ;cmp al,0h ;para zerar o AF, que de alguma forma
- aas ;atrapalha o Adjust After Subtraction
- mov [bx],al
- dec si
- dec di
- dec bx
- loop loop_subtr
- ret
- multiplicacao:
- ;realizada com sucessivas somas, achei dificil usar AAM
- ;obtem o numero1 em ax
- mov al,0h
- mov di,offset numero_1
- mov cx,4
- repe scasb ;enquanto CX!=0 && ZF==1
- dec di
- mov dx,di
- sub di,offset numero_1 ;obtenho a quantidade de elementos
- mov ax,4
- sub ax,di
- push ax
- push dx
- call char2dec
- ;obtem numero2 em bx
- mov al,0h
- mov di,offset numero_2
- mov cx,4
- repe scasb
- dec di
- mov dx,di
- sub di,offset numero_2 ;obtenho a quantidade de elementos
- mov ax,4
- sub ax,di
- push ax
- push dx
- call char2dec
- pop bx
- pop ax ;desempilha para ax depois, já que ax é utilizado
- ;no processo de obter o numero2, XD
- ;verifica qual dos dois é maior
- cmp ax,bx
- jnc prepara_ax ; ax>bx
- jc prepara_bx ; bx>ax
- jz prepara ; ax=bx
- prepara_ax:
- ;numero2 será contador
- mov cx,bx
- sub cx,1
- mov dx,cx ; backup de cx
- jc mult_final ; se numero_2 = 0
- mov cx,4
- mov si,offset numero_1
- mov di,offset resultado
- rep movsb
- mov cx,dx ; volta valor antigo de cx
- jz mult_final ; se numero_2 = 1
- mov si,offset resultado + 3
- mov di,offset numero_1 + 3
- push si
- push di
- push si
- mult_soma_ax:
- mov dx,cx
- call soma
- mov cx,dx
- loop mult_soma_ax
- add sp,6 ; para ajustar o stack para CS:IP correto
- ret
- prepara_bx:
- ;numero1 será contador
- mov cx,ax
- sub cx,1
- mov dx,cx
- jc mult_final ; se numero_1 = 0
- mov cx,4
- mov si,offset numero_2
- mov di,offset resultado
- rep movsb
- mov cx,dx
- jz mult_final ; se numero_1 = 1
- mov si,offset resultado + 3
- mov di,offset numero_2 + 3
- push si
- push di
- push si
- mult_soma_bx:
- mov dx,cx
- call soma
- mov cx,dx
- loop mult_soma_bx
- add sp,6 ; para ajustar o stack para CS:IP correto
- ret 6
- prepara:
- ;numero2 será contador
- mov cx,bx
- sub cx,1
- mov dx,cx ; backup de cx
- jc mult_final ; se numero_2 = 0
- mov cx,4
- mov si,offset numero_1
- mov di,offset resultado
- rep movsb
- mov cx,dx ; volta valor antigo de cx
- jz mult_final ; se numero_2 = 1
- mov si,offset resultado + 3
- mov di,offset numero_1 + 3
- push si
- push di
- push si
- mult_soma:
- mov dx,cx
- call soma
- mov cx,dx
- loop mult_soma
- add sp,6 ; para ajustar o stack para CS:IP correto
- ret
- mult_final:
- add sp,6 ; para ajustar o stack para CS:IP correto
- ret
- divisao:
- mov bp,sp
- mov ax,[bp]
- mov [bp+8],ax
- add sp,2 ;para o topo da pilha descer 1 posição e apontar
- ;para o offset do resultado
- ;=== situacao do stack subtracao ===
- ; SP
- ;CallPrincipal N2 N1 RES(N1)
- ; +6 +4 +2 +0
- xor dx,dx
- div_subtr:
- mov bp,sp
- mov [bp] ,offset numero_1 + 3
- mov [bp+2],offset numero_1 + 3
- mov [bp+4],offset numero_2 + 3
- call subtracao
- mov bp,sp
- mov [bp], offset resultado + 3
- mov [bp+2],offset resultado + 3
- mov [bp+4],offset const_1 + 3
- call soma
- mov al,0h
- mov di,offset numero_1
- mov cx,4
- repe scasb ;enquanto CX!=0 && ZF==1
- jnz div_subtr ;se nao chegou no fim
- ;reorganiza todo o stack novamente
- mov bp,sp
- mov bx,[bp+6]
- mov ax,[bp+4]
- mov [bp+6],ax
- mov ax,[bp+2]
- mov [bp+4],ax
- mov ax,[bp]
- mov [bp+2],ax
- mov [bp],bx
- ;=== situacao do stack atual ===
- ; SP
- ;N2 RES(n1) RES CallPrincipal
- ;+6 +4 +2 +0
- ret
- operacoes endp
- ;======== entrada/saida =============
- char2dec proc near
- xor ax,ax
- xor bx,bx
- xor cx,cx
- mov bp,sp
- mov cl,[bp+4]
- mov di,0
- mov bx,[bp+2]
- ;=== rotina para transformar em decimal ===
- recalcula:
- dec cl
- push ax ;backup do valor anterior se tiver
- push dx ;somente para abrir espaco do resultado para ax
- push bx ;backup do offset
- push cx ;numero de casas, será usado em pow
- call pow
- pop cx ;recupera cx novamente
- pop bx ;recupera offset de linha
- pop dx ;numero obtido com a potencia de 10^cx-1
- mov al,[bx+di]
- mul dx
- mov dx,ax
- pop ax
- add dx,ax
- inc di
- mov ax,di
- cmp cl,al
- mov ax,dx ;numero a ser somado na proxima
- jnc recalcula
- fim_calculo:
- mov bp,sp
- mov [bp+4],ax
- ret 2
- char2dec endp
- ;======== ajustes de base/numero ======
- pow proc near
- mov bp,sp
- mov cx,[bp+2]
- or cx,cx
- jz pow_final_zero
- mov bx,10h
- dec cx
- jz pow_final
- mov ax,10h
- mult:
- mul bx
- dec cx
- jnz mult
- mov [bp+6],ax
- ret
- pow_final_zero:
- mov ax,1h
- mov [bp+6],ax
- ret
- pow_final:
- mov ax,10h
- mov [bp+6],ax
- ret
- pow endp
- prepara_numero proc near
- mov bp,sp
- mov di,[bp+2]
- mov ax,0h
- mov al,4
- sub al,tam_linha
- add di,ax
- mov si,offset linha
- xor cx,cx
- cld
- prossegue:
- cmp tam_linha,cl
- jz final
- lodsb
- sub al,30h
- stosb
- inc cl
- jmp prossegue
- final:
- ret 2
- prepara_numero endp
- ler_linha proc near
- mov ah,0Ah
- int 21h
- ret
- ler_linha endp
- printChar proc near
- mov ah,02h
- int 21h
- ret
- printChar endp
- print proc near
- mov ah,09h
- int 21h
- ret
- print endp
- ;====================================
- codigo ends
- end inicio
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement