Advertisement
DavidsonDFGL

Calculadora by CyberBatman

Jul 5th, 2013
366
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;============ calc by CyberBatman =========
  2. max_lin equ 4   ;tamanho maximo linha
  3. cr equ 0Dh      ;carriage return
  4. lf equ 0Ah      ;line feed
  5.  
  6. stack segment stack          
  7.     dw 128 dup(?)             ;128 words pilha
  8.     topo_da_pilha label word  ;delimita o começo da pilha
  9. stack ends
  10.  
  11. dados segment
  12.     area_leitura db max_lin        ;numero maximo de caracteres
  13.     tam_linha    db ?              ;numero caracteres lidos
  14.     linha        db max_lin dup(0) ;caracteres lidos
  15.    
  16.     numero_1     db 4 dup(0)       ;primeiro numero
  17.     numero_2     db 4 dup(0)       ;segundo numero
  18.     resultado    db 4 dup(0)       ;resultado da operacao
  19.    
  20.     tab_operadores db '+-*/'       ;operadores validos
  21.     n_operadores  equ 4            ;numero operadores
  22.    
  23.     newl         db cr,lf,'$'
  24.     const_1      db 0,0,0,1h       ;constante de valor 1
  25.    
  26.     tab_func     dw offset soma      ;contem endereco dos labels das subrotinas
  27.                  dw offset subtracao
  28.                  dw offset multiplicacao
  29.                  dw offset divisao
  30.                  
  31.     apresentacao db cr,lf
  32.                  db 'Calculadora CyberBat 2014'
  33.                  db cr,lf
  34.                  db '$'
  35.                  
  36.     comando1     db cr,lf,'CCB> Numero1 : ','$'
  37.     comando2     db cr,lf,'CCB> Numero2 : ','$'
  38.     comando3     db cr,lf,'CCB> Operando:','$'
  39.    
  40.     msg_resul    db cr,lf,'Resultado:','$'    
  41. dados ends
  42.  
  43. codigo segment
  44.     inicio:  
  45.         mov ax,stack   ;define segmento de pilha no registrador
  46.         mov ss,ax
  47.         mov sp,offset topo_da_pilha
  48.        
  49.         mov ax,dados   ;define segmento de dados no registrador
  50.         mov ds,ax
  51.         mov es,ax
  52.        
  53.         mov dx,offset apresentacao
  54.         call print
  55.        
  56.     principal:
  57.         ;=======leitura e preparação dos numeros=====
  58.         mov dx,offset comando1
  59.         call print    
  60.        
  61.         mov dx,offset area_leitura
  62.         call ler_linha
  63.        
  64.         mov dx,offset numero_1
  65.         push dx
  66.         call prepara_numero
  67.                              
  68.         ; ** repete para o 2 numero **
  69.         mov dx,offset comando2
  70.         call print    
  71.        
  72.         mov dx,offset area_leitura
  73.         call ler_linha
  74.        
  75.         mov dx,offset numero_2
  76.         push dx
  77.         call prepara_numero
  78.        
  79.         ;obtém o operando
  80.         mov dx,offset comando3
  81.         call print
  82.        
  83.         mov dx,offset area_leitura
  84.         call ler_linha
  85.        
  86.         ;prepara para chamar as operacoes (+,-,*,/)
  87.         xor ax,ax
  88.         mov al,linha
  89.         mov di,offset tab_operadores
  90.         mov cx,n_operadores
  91.        
  92.         repne scasb ;varre operadores em busca da posicao do operador informado
  93.         sub di,offset tab_operadores
  94.         dec di      ;subtrai 1 para voltar a posicao
  95.         sal di,1    ;*2 para ajustar para word
  96.        
  97.        
  98.         mov si,offset resultado + 3            
  99.         mov cx,offset numero_1  + 3
  100.         mov dx,offset numero_2  + 3
  101.  
  102.         push dx
  103.         push cx
  104.         push si
  105.        
  106.         call tab_func[di]
  107.         add sp,6
  108.        
  109.         mov dx,offset msg_resul
  110.         call print
  111.        
  112.         ;imprimir char por char do resultado      
  113.         mov cx,4h
  114.         mov si,offset resultado
  115.         imprimir_resp:
  116.             lodsb
  117.             add al,30h
  118.             mov dl,al
  119.             call printChar
  120.             loop imprimir_resp
  121.        
  122.         xor ax,ax
  123.         xor bx,bx
  124.         xor cx,cx
  125.         xor dx,dx
  126.        
  127.        
  128.        
  129.         hlt
  130.        
  131.         ;======== operacoes matematicas ========
  132.        
  133.         operacoes proc near
  134.             soma:
  135.                 mov bp,sp
  136.                 mov bx,[bp+2]            
  137.                 mov si,[bp+4]
  138.                 mov di,[bp+6]
  139.                
  140.                 clc
  141.                 mov cx,4
  142.                
  143.                 loop_soma:
  144.                     mov al,[si]
  145.                     adc al,[di]
  146.                     aaa
  147.                     mov [bx],al
  148.                     dec si
  149.                     dec di
  150.                     dec bx
  151.                     loop loop_soma        
  152.                 ret
  153.            
  154.             subtracao:
  155.                 ;obtem o numero1 em ax
  156.                 mov al,0h
  157.                 mov di,offset numero_1
  158.                 mov cx,4
  159.                 repe scasb  ;enquanto CX!=0 && ZF==1
  160.                 dec di
  161.                
  162.                 sub  di,offset numero_1 ;obtenho a quantidade de elementos
  163.                 mov  bx,4h
  164.                 sub  bx,di
  165.                                  
  166.                 ;obtem numero2 em bx
  167.                 mov al,0h
  168.                 mov di,offset numero_2
  169.                 mov cx,4
  170.                 repe scasb
  171.                 dec di
  172.                
  173.                 sub  di,offset numero_2 ;obtenho a quantidade de elementos
  174.                 mov  dx,4h
  175.                 sub  dx,di
  176.                        
  177.                 ;verifica qual dos dois é maior
  178.                 cmp bx,dx
  179.                 jnc bx_maior ; bx>dx
  180.                 jc  dx_maior ; dx>bx
  181.                 jz  iguais   ; bx=dx
  182.                
  183.                 bx_maior:
  184.                     mov cx, bx
  185.                     jmp prossegue_sub
  186.                 dx_maior:
  187.                     mov cx, dx
  188.                     jmp prossegue_sub
  189.                 iguais:
  190.                     mov cx, bx
  191.                     jmp prossegue_sub
  192.                    
  193.                 prossegue_sub:
  194.                 mov bp,sp
  195.                 mov bx,[bp+2]            
  196.                 mov si,[bp+4]
  197.                 mov di,[bp+6]
  198.                
  199.                 clc                
  200.                 loop_subtr:
  201.                     mov al,[si]
  202.                     sbb al,[di]
  203.                     ;cmp al,0h ;para zerar o AF, que de alguma forma
  204.                     aas       ;atrapalha o Adjust After Subtraction
  205.                     mov [bx],al
  206.                     dec si
  207.                     dec di
  208.                     dec bx
  209.                     loop loop_subtr
  210.                 ret
  211.                
  212.             multiplicacao:
  213.             ;realizada com sucessivas somas, achei dificil usar AAM
  214.            
  215.                 ;obtem o numero1 em ax
  216.                 mov al,0h
  217.                 mov di,offset numero_1
  218.                 mov cx,4
  219.                 repe scasb  ;enquanto CX!=0 && ZF==1
  220.                 dec di
  221.                
  222.                 mov  dx,di
  223.                 sub  di,offset numero_1 ;obtenho a quantidade de elementos
  224.                 mov  ax,4
  225.                 sub  ax,di
  226.                
  227.                 push ax
  228.                 push dx
  229.                 call char2dec
  230.                                  
  231.                 ;obtem numero2 em bx
  232.                 mov al,0h
  233.                 mov di,offset numero_2
  234.                 mov cx,4
  235.                 repe scasb
  236.                 dec di
  237.                
  238.                 mov  dx,di
  239.                 sub  di,offset numero_2 ;obtenho a quantidade de elementos
  240.                 mov  ax,4
  241.                 sub  ax,di
  242.                
  243.                 push ax
  244.                 push dx
  245.                 call char2dec
  246.                 pop  bx
  247.                 pop  ax  ;desempilha para ax depois, já que ax é utilizado
  248.                          ;no processo de obter o numero2, XD
  249.                
  250.                 ;verifica qual dos dois é maior
  251.                 cmp ax,bx
  252.                 jnc prepara_ax ; ax>bx
  253.                 jc  prepara_bx ; bx>ax
  254.                 jz  prepara    ; ax=bx
  255.                
  256.                 prepara_ax:
  257.                     ;numero2 será contador
  258.                     mov cx,bx
  259.                     sub cx,1
  260.                     mov dx,cx     ; backup de cx
  261.                     jc mult_final ; se numero_2 = 0
  262.                    
  263.                     mov cx,4
  264.                     mov si,offset numero_1
  265.                     mov di,offset resultado
  266.                     rep movsb
  267.                     mov cx,dx     ; volta valor antigo de cx
  268.                    
  269.                     jz mult_final ; se numero_2 = 1
  270.                                  
  271.                     mov si,offset resultado + 3
  272.                     mov di,offset numero_1  + 3
  273.                    
  274.                     push si
  275.                     push di
  276.                     push si
  277.                     mult_soma_ax:
  278.                         mov dx,cx
  279.                         call soma
  280.                         mov cx,dx  
  281.                         loop mult_soma_ax
  282.                        
  283.                     add sp,6      ; para ajustar o stack para CS:IP correto
  284.                     ret
  285.                    
  286.                 prepara_bx:
  287.                     ;numero1 será contador
  288.                     mov cx,ax
  289.                     sub cx,1
  290.                     mov dx,cx
  291.                     jc mult_final ; se numero_1 = 0
  292.                    
  293.                     mov cx,4
  294.                     mov si,offset numero_2
  295.                     mov di,offset resultado
  296.                     rep movsb
  297.                     mov cx,dx
  298.                    
  299.                     jz mult_final ; se numero_1 = 1
  300.                    
  301.                     mov si,offset resultado + 3
  302.                     mov di,offset numero_2  + 3
  303.                    
  304.                     push si
  305.                     push di
  306.                     push si
  307.                    
  308.                     mult_soma_bx:
  309.                         mov dx,cx
  310.                         call soma
  311.                         mov cx,dx
  312.                         loop mult_soma_bx
  313.                        
  314.                     add sp,6      ; para ajustar o stack para CS:IP correto
  315.                     ret 6
  316.                    
  317.                 prepara:
  318.                     ;numero2 será contador
  319.                     mov cx,bx
  320.                     sub cx,1
  321.                     mov dx,cx     ; backup de cx
  322.                     jc mult_final ; se numero_2 = 0
  323.                    
  324.                     mov cx,4
  325.                     mov si,offset numero_1
  326.                     mov di,offset resultado
  327.                     rep movsb
  328.                     mov cx,dx     ; volta valor antigo de cx
  329.                    
  330.                     jz mult_final ; se numero_2 = 1
  331.                                  
  332.                     mov si,offset resultado + 3
  333.                     mov di,offset numero_1  + 3
  334.                    
  335.                     push si
  336.                     push di
  337.                     push si
  338.                     mult_soma:
  339.                         mov dx,cx
  340.                         call soma
  341.                         mov cx,dx  
  342.                         loop mult_soma
  343.                     add sp,6      ; para ajustar o stack para CS:IP correto    
  344.                     ret  
  345.                    
  346.                 mult_final:
  347.                 add sp,6          ; para ajustar o stack para CS:IP correto        
  348.                 ret
  349.            
  350.             divisao:
  351.                 mov bp,sp
  352.                 mov ax,[bp]
  353.                 mov [bp+8],ax
  354.                                                
  355.                 add sp,2      ;para o topo da pilha descer 1 posição e apontar
  356.                               ;para o offset do resultado
  357.                              
  358.                 ;=== situacao do stack subtracao ===
  359.                 ;                         SP
  360.                 ;CallPrincipal  N2  N1  RES(N1)
  361.                 ;  +6           +4  +2    +0  
  362.                
  363.                 xor dx,dx
  364.                 div_subtr:
  365.                     mov bp,sp
  366.                     mov [bp]  ,offset numero_1 + 3
  367.                     mov [bp+2],offset numero_1 + 3
  368.                     mov [bp+4],offset numero_2 + 3
  369.                     call subtracao
  370.                    
  371.                     mov bp,sp
  372.                     mov [bp],  offset resultado + 3
  373.                     mov [bp+2],offset resultado + 3
  374.                     mov [bp+4],offset const_1   + 3
  375.                     call soma
  376.                    
  377.                     mov al,0h
  378.                     mov di,offset numero_1
  379.                     mov cx,4
  380.                     repe scasb  ;enquanto CX!=0 && ZF==1
  381.                                                  
  382.                     jnz div_subtr ;se nao chegou no fim
  383.                
  384.                 ;reorganiza todo o stack novamente
  385.                 mov bp,sp
  386.                 mov bx,[bp+6]
  387.                
  388.                 mov ax,[bp+4]
  389.                 mov [bp+6],ax
  390.                
  391.                 mov ax,[bp+2]
  392.                 mov [bp+4],ax
  393.                
  394.                 mov ax,[bp]
  395.                 mov [bp+2],ax
  396.                
  397.                 mov [bp],bx
  398.                
  399.                 ;=== situacao do stack atual ===
  400.                 ;                       SP
  401.                 ;N2  RES(n1)  RES CallPrincipal
  402.                 ;+6    +4     +2     +0        
  403.                
  404.                 ret
  405.         operacoes endp
  406.                
  407.         ;======== entrada/saida =============
  408.        
  409.         char2dec proc near        
  410.             xor ax,ax
  411.             xor bx,bx
  412.             xor cx,cx
  413.            
  414.             mov bp,sp
  415.             mov cl,[bp+4]
  416.             mov di,0
  417.             mov bx,[bp+2]
  418.             ;=== rotina para transformar em decimal ===
  419.             recalcula:        
  420.                 dec cl
  421.        
  422.                 push ax   ;backup do valor anterior se tiver
  423.                 push dx   ;somente para abrir espaco do resultado para ax
  424.                 push bx   ;backup do offset
  425.                 push cx   ;numero de casas, será usado em pow
  426.                 call pow
  427.                 pop  cx   ;recupera cx novamente
  428.                 pop  bx   ;recupera offset de linha
  429.                 pop  dx   ;numero obtido com a potencia de 10^cx-1
  430.        
  431.                 mov al,[bx+di]
  432.                 mul dx
  433.                 mov dx,ax
  434.        
  435.                 pop ax
  436.                 add dx,ax
  437.        
  438.                 inc di
  439.                 mov ax,di
  440.                 cmp cl,al
  441.        
  442.                 mov ax,dx ;numero a ser somado na proxima
  443.        
  444.                 jnc recalcula
  445.        
  446.                 fim_calculo:
  447.                     mov bp,sp
  448.                     mov [bp+4],ax
  449.                     ret 2
  450.         char2dec endp
  451.        
  452.         ;======== ajustes de base/numero ======
  453.         pow proc near
  454.             mov bp,sp
  455.             mov cx,[bp+2]
  456.             or cx,cx
  457.            
  458.             jz pow_final_zero
  459.             mov bx,10h
  460.             dec cx
  461.             jz pow_final
  462.            
  463.             mov ax,10h
  464.             mult:
  465.                 mul  bx
  466.                 dec  cx
  467.                 jnz mult
  468.                 mov [bp+6],ax
  469.                 ret            
  470.            
  471.             pow_final_zero:
  472.                 mov  ax,1h
  473.                 mov [bp+6],ax
  474.                 ret
  475.                
  476.             pow_final:
  477.                 mov ax,10h
  478.                 mov [bp+6],ax
  479.                 ret  
  480.         pow endp
  481.        
  482.         prepara_numero proc near
  483.             mov bp,sp
  484.             mov di,[bp+2]
  485.            
  486.             mov ax,0h                
  487.             mov al,4
  488.             sub al,tam_linha
  489.             add di,ax
  490.                        
  491.             mov si,offset linha
  492.             xor cx,cx
  493.              
  494.             cld
  495.             prossegue:
  496.                 cmp tam_linha,cl
  497.                 jz final
  498.                 lodsb
  499.                 sub al,30h
  500.                 stosb
  501.                 inc cl
  502.                 jmp prossegue
  503.             final:
  504.                 ret 2          
  505.         prepara_numero endp
  506.        
  507.         ler_linha proc near
  508.             mov ah,0Ah
  509.             int 21h      
  510.             ret
  511.         ler_linha endp
  512.        
  513.         printChar proc near
  514.             mov ah,02h
  515.             int 21h
  516.             ret
  517.         printChar endp
  518.        
  519.         print proc near
  520.             mov ah,09h
  521.             int 21h
  522.             ret
  523.         print endp
  524.        
  525.         ;====================================
  526.  
  527. codigo ends
  528.  
  529. end inicio
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement