;Nome: Luiz Erivelto de Oliveira Jr - RA: 97427

;Trabalho de Linguagem de Montagem para o 2o Sementre de 2001

;Leitura de N notas, com calculo da media

;Identificar e mostrar quais notas sao menores que 1/4 da media
;Identificar e mostrar quais notas sao maiores que 3/4 da media

         ;----------------------------------------------------
         ;As Proximas Linhas definem o tamanho da minha Pilha 
         ;----------------------------------------------------

Pilha Segment para Stack 'Stack'
      Db 256 Dup(0)
Pilha Ends

         ;--------------------------------------------
         ;As Proximas Linhas definem minhas variaveis 
         ;--------------------------------------------

Dados Segment para Public 'Data'
      MsgAviso   Db 13,10,' O Sistema aceita ate 9999 notas, para sair digite uma nota maior que 10 $'
      MsgNota    Db 13,10,' Digite a Nota: $'
      MsgMedia   Db 10,13,' Media = '
      MediaAsc   Db 6 Dup(0),10,13,'$'
      Media      Dw 0
      MsgVal14   Db 13,10,' 1/4 da Media = '
      MenorAsc   Db 6 Dup(0),10,13,'$'
      MsgVal34   Db 13,10,' 3/4 da Media = '
      MaiorAsc   Db 6 Dup(0),10,13,'$'
      Msg14      Db ' Notas Menores que 1/4 da Media',13,'$'
      Msg34      Db ' Notas Maiores que 3/4 da Media',13,'$'
      Menor      Dw 0
      Maior      Dw 0
      Soma       Dw 0
      Acumulador Dw 0
      Numeros    Dw 9999 Dup(0)
      MsgResul   Db 13,10,' Nota = '
      NumAsc     Db 6 Dup(0),'$'
Dados Ends

         ;----------------------------------------------
         ;O Programa comeca efetivamente a partir daqui
         ;----------------------------------------------

Prog Segment para Public 'Code'

      Assume Cs:Prog,Ds:Dados,Es:Dados
      Org    100h
      Inicio Proc Far

         ;---------------------------------------------------------------------
         ;As Proximas Linhas Zeram os Contadores e joga minhas Variaveis neles 
         ;---------------------------------------------------------------------

         Push Ds                     ;Salvo DS na Pilha
         Xor Ax,Ax                   ;Zero Ax - MOV Ax,0
         Push Ax                     ;Salvo Ax na Pilha
         Mov Ax,Dados                ;Movo minhas variaveis para Ax
         Mov Ds,Ax                   ;Movo minhas variaveis para Ds
         Mov Es,Ax                   ;Movo minhas variaveis para Es

         ;-------------------------
         ;Mostra Mensagem de Aviso
         ;-------------------------

         Mov Dx,OffSet MsgAviso      ;Jogo a Mensagem de Aviso para Dx para Exibila na Tela
         Call Mostra                 ;Exibo a Mensagem de Nota na Tela (Rotina Externa)
         Call PulaLinha              ;Pula uma Linha (Rotina Externa)

         ;----------------------------
         ;Inicio da Leitura das Notas
         ;----------------------------

         Mov Soma,0                  ;Zera minha Soma
         Mov Acumulador,0            ;Zera meu Acumulador
         Mov Di,OffSet Numeros       ;Jogo Numeros em Di para efetuar a leitura das notas

    Ler: Cmp Acumulador,9999         ;Compara o Acumulador com 9999 (Numero Maximo de Notas)
         Je CMedia                   ;Se for Igual a 9999, Vai para Continua e Termina a Leitura das notas

         Mov Dx,OffSet MsgNota       ;Jogo a Mensagem de Nota para Dx para Exibila na Tela
         Call Mostra                 ;Exibo a Mensagem de Nota na Tela (Rotina Externa)
         Call LerInt                 ;Leio a Nota e Jogo o valor em Ax (Rotina Externa)

         ;------------------------------------------------------------------------------------------------
         ;As Proximas Linhas fazem a Verificacao da Nota Digitada para Ver se Continua a Ler Outras Notas
         ;------------------------------------------------------------------------------------------------

         Cmp Ax,10                   ;Compara a Nota digitada com 10
         Ja CMedia                   ;Se for Maior que 10, Vai para Continua e Termina a Leitura das notas

         ;---------------------------------------------------------------------------
         ;As Proximas Linhas fazem a soma da Nota digitada na Soma de Todas as Notas
         ;---------------------------------------------------------------------------

         Add Soma,Ax                 ;A nota digitada eh valida, entao soma ela em Soma
         Mov [Di],Ax                 ;Move a Nota Digitada para Di

         
         Add Di,2                    ;Vai Para o Proximo Endereco de Di, ja que Numeros eh Word
         Add Acumulador,1            ;Soma 1 ao Acumulador
         Jmp Ler                     ;E volta para Ler, para Ler Mais uma Nota

         ;--------------------------------------------
         ;As Proximas Linhas fazem o Calculo da Media
         ;--------------------------------------------

CMedia:  Mov Dx,0                    ;Move 0 para Dx para Calcular a Media
         Mov Ax,Soma                 ;Move Soma para Ax porque ele eh o Dividendo
         Mov Bx,Acumulador           ;Move Acumulador para Bx porque ele eh o Divisor
         Cmp Bx,0                    ;Verifica se houve Notas Digitadas
         Je  DivZero                 ;Nao, entao vai para DivZero
         IDiv Bx                     ;Divide Ax por Bx (Soma pelo Acumulador) Acumulador = Qtde de Notas

DivZero: Mov Media,Ax                ;Coloca a media calculada (Ax) em Media

         ;---------------------------------------------------------
         ;As Proximas Linhas fazem o Calculo de 1/4 e 3/4 da Media
         ;---------------------------------------------------------

         Mov Dx,0                    ;Move 0 para Dx para Calcular 1/4 da Media
         Mov Bx,4                    ;Move 4 para Bx para Dividir a Media por 4
         IDiv Bx                     ;Divide Ax (Media) por Bx (4) obtendo assim 1/4 da Media
         Mov Menor,Ax                ;Move Ax (1/4 da Media) para Menor
         Mov Dx,0                    ;Move 0 para Dx para Calcular 3/4 da Media
         Mov Bx,3                    ;Move 3 para Bx para Multiplicar 1/4 por 3
         IMul Bx                     ;Multiplica Ax (1/4) por Bx (3) obtendo assim 3/4 da Media
         Mov Maior,Ax                ;Move Ax (3/4 da Media) para Maior

         ;-------------------------------------------
         ;As Proximas Linhas exibem o valor da Media
         ;-------------------------------------------

         Call PulaLinha              ;Pula uma Linha (Rotina Externa)
         Mov Ax,Media                ;Move a Media para Ax pois eh ele que sera exibido
         Mov Di,OffSet MediaAsc      ;Joga MediaAsc em Di
         Call DecAsc                 ;Essa Rotina Externa converte um Numero em uma String
         Mov Dx,OffSet MsgMedia      ;Move a Mensagem da Media para Dx
         Call Mostra                 ;Mostra a Mensagem de Media na Tela (Rotina Externa)

         ;------------------------------------------------------------
         ;As Proximas Linhas exibem as notas Menores que 1/4 da media
         ;------------------------------------------------------------

         Mov Ax,Menor                ;Move Menor para Ax pois eh ele que sera exibido
         Mov Di,OffSet MenorAsc      ;Joga NumAsc em Di
         Call DecAsc                 ;Essa Rotina Externa converte um Numero em uma String
         Mov Dx,OffSet MsgVal14      ;Joga a Mensagem do Valor de 1/4 em Dx
         Call Mostra                 ;Exibe a Mensagem na Tela

         Mov Dx,OffSet Msg14         ;Joga a Mensagem de 1/4 em Dx
         Call Mostra                 ;Exibe a Mensagem na Tela

         Mov Di,OffSet Numeros       ;Jogo Di para Numeros para efetuar a leitura das notas
         Mov Cx,0                    ;Zera Cx pois ele sera meu Novo Acumulador
Menores: Mov Ax,[Di]                 ;Nao terminou, entao Move a Nota para Ax
         Cmp Ax,Menor                ;Compara Ax (Nota) com Menor (1/4 da Media)
         Jae NMenor                  ;Se nao for menor que Menor, vai para NMenor
         Push Di                     ;Opa, eh menor, entao Salva Di na Pilha
         Mov Di,OffSet NumAsc        ;Joga NumAsc em Di
         Call DecAsc                 ;Converte um Numero em uma String (Rotina Externa)
         Mov Dx,OffSet MsgResul      ;Joga MsgResul em Dx
         Call Mostra                 ;Exibe a Nota na Tela
         Pop Di                      ;Recupera Di da Pilha
NMenor:  Add Cx,1                    ;Acrescenta 1 a Cx
         Cmp Cx,Acumulador           ;Compara Cx ao Acumulador (Qtde de Notas)
         Je  Proximo                 ;Eh igual, entao terminou, va para Proximo
         Add Di,2                    ;Vai 2 Enderecos para frente em Di
         Jmp Menores                 ;Comeca Tudo de Novo

         ;------------------------------------------------------------
         ;As Proximas Linhas exibem as notas Maiores que 3/4 da media
         ;------------------------------------------------------------

Proximo: Call PulaLinha              ;Pula uma Linha (Rotina Externa)
         Mov Ax,Maior                ;Move Maior para Ax pois eh ele que sera exibido
         Push Di                     ;Salva Di na Pilha
         Mov Di,OffSet MaiorAsc      ;Joga NumAsc em Di
         Call DecAsc                 ;Essa Rotina Externa converte um Numero em uma String
         Mov Dx,OffSet MsgVal34      ;Joga a Mensagem do Valor de 3/4 em Dx
         Call Mostra                 ;Exibe a Mensagem na Tela
         Pop Di                      ;Recupera Di da Pilha

         Mov Dx,OffSet Msg34         ;Joga Mensagem de 3/4 em Dx
         Call Mostra                 ;Exibe a Mensagem na Tela

         Mov Di,OffSet Numeros       ;Jogo Di em Numeros para efetuar a leitura das notas
         Mov Cx,0                    ;Zera Cx pois ele sera meu Novo Acumulador
Maiores: Mov Ax,[Di]                 ;Nao terminou, entao Move a Nota para Ax
         Cmp Ax,Maior                ;Compara Ax (Nota) com Maior (1/4 da Media)
         Jbe  NMaior                 ;Se nao for maior que Maior, vai para NMaior
         Push Di                     ;Opa, eh maior, entao Salva Di na Pilha
         Mov Di,OffSet NumAsc        ;Joga NumAsc em Di
         Call DecAsc                 ;Converte um Numero em uma String (Rotina Externa)
         Mov Dx,OffSet MsgResul      ;Joga MsgResul em Dx
         Call Mostra                 ;Exibe a Nota na Tela
         Pop Di                      ;Recupera Di da Pilha
NMaior:  Add Cx,1                    ;Acrescenta 1 a Cx
         Cmp Cx,Acumulador           ;Compara Cx ao Acumulador (Qtde de Notas)
         Je  Fim                     ;Eh igual, entao terminou, va para Fim
         Add Di,2                    ;Vai 2 Enderecos para frente em Di
         Jmp Maiores                 ;Comeca Tudo de Novo

Fim:     Call PulaLinha              ;Pula uma Linha (Rotina Externa)
         Ret
     Inicio Endp
     Extrn DecAsc:Near
     Extrn Mostra:Near
     Extrn LerInt:Near
     Extrn PulaLinha:Near
Prog Ends
End Inicio
