Editor de texto em Assembly 1 - Versão final


Kássio Rômulo Lima Sousa – CP09126-81
EDITOR DE TEXTO EM ASSEMBLY DESENVOLVIDO
PARA A CADEIRA DE ARQUITERURA DE COMPUTADORES

Principais funções:
·         Escrita.
·         Justificação do texto.
·         Localiza uma palavra no texto e substitui  por outra também definida pelo usuário.
·         Salva o arquivo digitado em formato “txt”.
·         Carrega um arquivo no mesmo diretório de formato “txt”.



%OUT--------------------------------------------------------------------------
%OUT Editor de texto - Escrever e justificar o texto                         -
%OUT Autor: Kassio Romulo Lima Sousa - CP09126-81 -                          -
%OUT--------------------------------------------------------------------------

.model small  ;tamanho do segmento de dados
.stack 100h   ;tamanho da pilha
.data         ;segmento de dados, com definições de variáveis

msgbusca db "Escreva a palavra para busca:$"
subs db "Escreva a palavra para substituir:$"
Msg    db    "Editor de Texto",0dh,0ah,"Digite a opcao desejada:",0dh,0ah,"1-Digitar o texto",0dh,0ah,"2-Buscar palavra no texto",0dh,0ah,"3-Sair",0dh,0ah,"4-Salvar e sair",0dh,0ah,"5-carregar",0dh,0ah,'$'

arquivotexto      DB     "ARQUIVO.txt"
AUX1        DW    ?
BUFFER2        DB    ?
SALVOU        DB    "O arquivo: arquivo.txt foi salvo no diretorio padrao'$'"

texto DB 2500 DUP ('$')
busca DB 100 DUP ('$')
subst DB 100 DUP ('$')


.code
INICIO:                    ;Inicia o segmento de dados apontando para o início da área de dados

MENU_REPETIÇAO:
        mov SI,0        ;Inicializa SI com 0h
        mov ax,@data
        mov ds,ax           

MENU1:
        call LIMPATELA

        LEA    DX,Msg        ; obtem o endereço efetivo de Msg
        MOV    AH,09h         ; move valor 09h para o registrador AH (imprime a string na tela)
        INT    21h        
   
MENU:
        MOV AH,1H       ;FUNÇÃO PARA LER (O CHAR FICA EM AL)  
        INT 21H
        CMP AL,'1'        ;Compara o caractere lido com '1'
        JE CASE_1
        CMP AL,'2'        ;Se for igual, da jump para o label CASE_1
        JE CASO2
        cmp al,'3'
        je SAINDO
        CMP AL,'4'        ;Se for igual, da jump para o label CASE_1
        JE CASO4
        CMP AL,'5'        ;Se for igual, da jump para o label CASE_1
        JE CASO5
        jmp MENU        ;No caso Default, o programa Retorna ao menu

CASO2:  jmp CASE_2
CASO4:     jmp SALVAR
CASO5:  jmp CARREGAR
SAINDO: jmp FIM

COMMENT*------------------------------------------------------------------------------
- Caso 1: Utilizado para escrita no editor
-------------------------------------------------------------------------------------*

CASE_1:
        call LIMPATELA          ;Limpa a tela para digitação
        call IMPRIME

LOOP_ESC:                        ;Fica no Loop ateh o usuario pressionar ESC
        MOV AH,1H                 ;FUNÇÃO PARA LER (O CHAR FICA EM AL)  
        INT 21H
        CMP AL,1Bh                ;compara AL com o caractere ESC
        JE    MENU1                ;Se a comparacao for verdadeira, efetua um Jump para a parte das opçoes novamente
        CMP AL, 08h                ;Compara o caractere lido com Backspace
        JE    CARAC_BACKSPACE        ;Se a comparacao for verdadeira efetua a ação
        CMP AL,0Dh                ;Compara o caractere lido com enter
        JE CARAC_ENTER            ;Se a comparacao for verdadeira vai para a função de ENTER
        MOV texto[SI],AL        ;Copia o caractere armazenado em AL para o espaco especificado por SI no vetor texto
        INC SI

        mov ah,3h              ;esta função retorna em dl a coluna
        int 10h
        cmp dl,79                ;80 é a ultima coluna
        je JUSTIFICAR             ;MOV TEXTO[SI],AL

        jmp LOOP_ESC            ;Efetua o Loop para pedir nova entrada de caractere guardando SI na pilha

;======================
CARAC_BACKSPACE:                ;Efetuado quando o usuario digita o caractere "BACKSPACE"
        CMP SI,0                ;Se for o inicio do texto,nao faz nada e pede nova entrada
        JE LOOP_ESC                ;Efetua o Loop para pedir nova entrada de caractere, Sem decrementar o contador CX
        CALL BACKSPACE            ;Pula para o label BACKSPACE       
        DEC SI                    ;Caso nao, decrementa SI
        MOV texto[SI],'$'        ;Coloca ,no espaco do vetor texto especificado por SI, o caractere '$'
        CALL LIMPATELA
        CALL IMPRIME
        JMP LOOP_ESC            ;Efetua o Loop para pedir nova entrada de caractere,Sem decrementar o contador CX

CARAC_ENTER:                    ;Efetuado quando o usuario digita o caractere "ENTER"
        call ENTER1
        mov texto[SI],AL        ;Copia o caractere armazenado em AL para o espaco especificado por SI no vetor texto
        inc SI                    ;Incrementa SI para apontar para a próxima posicao do Vetor
        loop LOOP_ESC            ;Efetua o Loop para pedir nova entrada de caractere
        jmp MENU_REPETIÇAO        ;mostra o resultado da busca

COMMENT*------------------------------------------------------------------------------
- Funções para justificar
-------------------------------------------------------------------------------------*

JUSTIFICAR:           
    mov ah,1h        
    int 21h
    cmp al,08h
    je CARAC_BACKSPACE
    cmp al,0dh
    je CARAC_ENTER
    mov texto[si],al
    inc si
    mov ah,1h        
    int 21h
    cmp al,08h
    je CARAC_BACKSPACE
    cmp al,0dh
    je CASE_1
    cmp al,' '
    je CASE_1
    mov texto[si],al
    xor bl,bl
;===============================================================
;Auxiliar para compara a chega de um espasço   
AUX3:
    dec si
    inc bl         
    cmp texto[si],' '
    je  SAIR_AUX3
    jmp AUX3
;===============================================================
;Sai da função acima   
SAIR_AUX3:
;===============================================================
;Copia a palvra antes do espaço para uma posição acima
VOLTARP:
    cmp texto[si],'$'
    je  SAIR_VOLTARP
    mov al,texto[si+1]
    mov texto[si],al
    inc si
    jmp VOLTARP
;===============================================================
;Sai da função acima
SAIR_VOLTARP:
    dec si
    push si
;===============================================================
;Auxilia o escrever espaço
ESCREVE_ESPACO:
    pop si                        ;Copia o valor em si
    push si                        ;Armazena o valor novamente
    mov cx,80
;===============================================================
;Verifica se é espaço
ESPACO:
    dec  si
    cmp  texto[si],' '
    jne  NO_DESLOCATXT
    call DESLOCATXT
;===============================================================
;Nao desloca o texto enquanto não for espaço
NO_DESLOCATXT:
    cmp  bl,0
    je   SAIR_ESCREVE_ESPACO
    loop ESPACO
    jmp  ESCREVE_ESPACO
;===============================================================
;Cancela a ação da função ESCREVE_ESPACO
SAIR_ESCREVE_ESPACO:
    jmp CASE_1
;===============================================================
;Armazena na pilha antes de deslocar o texto
DESLOCATXT:
    push si
    push ax
    push dx
    mov ax,si             
;===============================================================
;Chega a fim do texto
FIM_TXT:
    inc si
    cmp texto[si],'$'
    je  SAIR_FIM_TXT
    jmp FIM_TXT
;===============================================================
;Sai da função acima
SAIR_FIM_TXT:
    dec si
;===============================================================
;Deslocamento do texto para a inserção de espaço
DESLOCAMENTO:
    cmp ax,si
    je  SAIR_DESLOCAMENTO
    mov dl,texto[si]
    mov texto[si+1],dl
    dec si
    jmp DESLOCAMENTO
;===============================================================
;Sai da função acima
SAIR_DESLOCAMENTO:
    mov texto[si+1],' '
    dec bl
    pop dx
    pop ax
    pop si
;===============================================================
;Insere os espaços
DECREMENTA_SI:
    dec si
    dec cx
    cmp texto[si],' '
    jne SAIR_DECREMENTA_SI
    cmp si,0
    je  SAIR_DECREMENTA_SI
    jmp DECREMENTA_SI
;===============================================================
;Sai da função acima
SAIR_DECREMENTA_SI:
    inc si
    retn
;===============================================================

COMMENT*------------------------------------------------------------------------------
- Funções para busca
-------------------------------------------------------------------------------------*
CASE_2:
        XOR SI,SI
PROCURA_STRING:           
        CALL LIMPATELA        ;Limpa a tela
        LEA DX,MSGBUSCA     ;string a ser exibida
        MOV AH,09h             ;função para exibir string       
        INT 21h
        CALL ENTER1

ESCREVE_PALAVRA_BUSCA:       
        MOV AH,01h             ;função DOS para receber um caractere
        INT 21h
        CMP AL,0Dh             ;compara com a tecla enter
        JE STRING_SUB         ;se enter foi pressionada, a rotina para escrita da palavra de substituir é iniciada
        CMP al,08h             ;compara com a tecla backspace
        JE FUNCBACKSPACE    ;Se for pressionada, a função backspace é iniciada
        MOV BUSCA[SI],AL     ;se não, guarda o caractere digitado no vetor BUSCA
        INC SI
        JMP ESCREVE_PALAVRA_BUSCA ;volta ao início da rotina até que enter seja pressionado
       
STRING_SUB:
        xor si,si
        CALL LIMPATELA        ;Limpa a tela
        LEA DX,SUBS         ;string a ser exibida
        MOV AH,09h             ;função para exibir string       
        INT 21h
        CALL ENTER1

ESCREVE_PALAVRA_SUB:       
        MOV AH,01h             ;função DOS para receber um caractere
        INT 21h
        CMP AL,0Dh             ;compara com a tecla enter
        JE PERCORRE_VET     ;se enter foi pressionada, a rotina de busca é iniciada
        CMP al,08h             ;compara com a tecla backspace
        JE FUNCBACKSPACE2    ;Se for pressionada, a função backspace é iniciada
        MOV SUBST[SI],AL     ;se não, guarda o caractere digitado no vetor SUBST
        INC SI
        JMP ESCREVE_PALAVRA_SUB ;volta ao início da rotina até que enter seja pressionado

;================
FUNCBACKSPACE: JMP CARAC_BACKSPACE
FUNCBACKSPACE2: JMP CARAC_BACKSPACE
;================
       
COMMENT*------------------------------------------------------------------------------
- Inicia as rotinas de busca:
    - Procura a primeira letra da palavra a ser buscada no vetor TEXTO
    - Se encontrar, compara cada caractere a partir dela nos vetores TEXTO e PALAVRA
    - Se a comparação for bem sucedida substitui as palavras encontradas
-------------------------------------------------------------------------------------*
PERCORRE_VET:           
        CALL LIMPATELA
        XOR SI,SI             ;zera SI para utilizalo como contador

PERCORRE_VET_BUSCA:       
        CMP TEXTO[SI],'$'     ;compara a posição SI do vetor (inical em 0) com o caractere $
        JE RETORNA_MENU     ;se for igual encerra a comparação
        MOV AL,BUSCA[0]     ;coloca a primeira posição do vetor em AL
        CMP SI,0             ;esse teste verifica se ainda está na primeira iteração
        JE PULA_TESTE         ;se estiver o teste adiante é desnecessário
        CMP TEXTO[SI-1],' ' ;se não estiver verifica se o caractere anterior é ' '(espaço)
        JNE REINICIA        ;Se não for vai para a função reinicia

PULA_TESTE:               
        CMP TEXTO[SI],AL     ;verifica se a primeira letra do vetor guardada em AL é igual ao elemento do vetor TEXTO em questão
        JNE REINICIA         ;se não forem iguais aciona uma rotina que reinicia a busca para imprimir o caracter desnecessário

TESTAR_IGUALDADE:       
        XOR BX,BX
        MOV AH,2H             ;FUNÇÃO PRA IMPRIMIR
        MOV DL,TEXTO[SI]      ;O QUE VAI SER IMPRESSO FICA EM DL
        INT 21H

TESTE_IGUALDADE:               
        inc BX                 ;incrementa a cada iteração do LOOP
        inc si                 ;incrementa a cada iteração do LOOP
        cmp TEXTO[SI],' '     ;verifica se espaço foi encontrado, que indica o final de uma palavra no vetor texto
        je FIM_TESTE_BUSCA     ;se encontrar um espaço encerra a iteração
        cmp TEXTO[SI],'$'     ;verifica se o caractere '$' foi encontrado, que indica o final do vetor texto
        je FIM_TESTE_BUSCA     ;se encontrar o cactere descrito acima encerra a iteração
        push si             ;guarda SI na pilha, guarda si para "gravar" a posição atual da primeira letra
        mov si,bx             ;coloca BX em SI, BX faz a iteração do início do vetor a cada teste
        cmp BUSCA[si],'$'     ;verifica se a palavra chegou ao fim
        je TIRA_POP
        pop si                ;Recupera o valor de SI
        mov al,TEXTO[si]     ;coloca o caractere da posição SI em AL para efetuar uma comparação adiante
        push si             ;guarda o valor atual de SI
        mov si,bx             ;coloca BX em SI para continuar com a iteração no LOOP
        cmp al,BUSCA[si]     ;compara o caractere do vetor TEXTO em AL com o caractere do vetor PALAVRA na posição SI
        jne TIRA_POP         ;se forem diferentes encerra a iteração
        pop si
        mov ah,2h             ;função pra imprimir
        mov dl,TEXTO[si]    ;o que vai ser impresso fica em dl
        int 21h
        jmp TESTE_IGUALDADE

TIRA_POP:                   
        pop si                 ;tira si da pilha
        jmp FIM_TESTE_BUSCA

REINICIA:                ;Se o caracter não faz parte da busca, é impressa na tela
        mov ah,2h                 ;função pra imprimir
        mov dl,TEXTO[si]        ;o que vai ser impresso fica em dl
        int 21h
        inc si
        jmp PERCORRE_VET_BUSCA     ;volta para procurar a primeira letra após a última encontrada e impressa

;=============================================
RETORNA_MENU:           
        mov ah,1h       ;função para ler e dar tempo de aparecer na tela as palavras coloridas
        int 21h
        jmp MENU1         ;encerra a busca e retorna ao menu
;==============================================
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
JMP_PERCORRE_VETOR_BUSCA:        jmp PERCORRE_VET_BUSCA
JMP_APAGA_LINHA:        jmp CARAC_BACKSPACE
JMP_LP_ESCREVE:         jmp LOOP_ESC
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

FIM_TESTE_BUSCA:           
        push si                 ;guarda si para não perder o valor ao realizar a operação adiante
        mov si,bx                 ;coloca BX em SI
        cmp BUSCA[si],'$'         ;verifica se a palavra chegou ao fim
        je VERIFICA_TEXTO_BUSCA
        pop si                     ;recupera o valor de SI
        jmp JMP_PERCORRE_VETOR_BUSCA
   
VERIFICA_TEXTO_BUSCA:           
        pop si                     ;recupera o valor de si guardado na rotina FIM_TESTE_BUSCA
        cmp TEXTO[si],' '         ;compara a posição si do vetor TEXTO com ' '
        je TESTANDO
        cmp TEXTO[si],'$'
        je TESTANDO
        jmp JMP_PERCORRE_VETOR_BUSCA
   
TESTANDO:                   
        cmp si,0             ;condição de parada
        je CONTINUA2         ;se SI for zero então está no início da palavra
        dec si                 ;decrementa SI até chegar na condição de parada
        cmp TEXTO[si],' '     ;ao encontrar um espaço aciona a rotina que vai colorir a palavra encontrada
        je CONTINUA
        mov ah,2h             ;função pra imprimir
        mov dl,08h            ;o que vai ser impresso fica em dl
        int 21h
        jmp TESTANDO

CONTINUA:               
        inc si   
CONTINUA2:
        xor bx,bx
SUBSTITUI:
       
        cmp TEXTO[si],' '         ;compara a posição SI do vetor TEXTO com ' ', essa a condição de parada do LOOP
        je JMP_PERCORRE_VETOR_BUSCA
        cmp TEXTO[si],'$'         ;compara a posição SI do vetor TEXTO com ' ', essa a condição de parada do LOOP
        je JMP_PERCORRE_VETOR_BUSCA
        cmp SUBST[BX],'$'         ;outra condição de parada do LOOP
        je JMP_PERCORRE_VETOR_BUSCA
        mov dl,SUBST[bx]
        mov TEXTO[si],dl
       
        mov ah,2h
        mov dl,TEXTO[si]
        int 21h
        inc si
        inc bx

        jmp SUBSTITUI   


COMMENT*------------------------------------------------------------------------------
- Funções complementares de todo o programa
-------------------------------------------------------------------------------------*

LIMPATELA:                    ; Limpa e Ajusta a tela
        PUSH AX                ; Guarda AX na pilha
        MOV AH,0H             ; Ativa a IRQ 10 para a limpeza do vídeo
        MOV AL,3H             ; define o modo de video
        int 10h               ; Habilita a IRQ 10 (video)
        POP AX                ; Recupera AX da pilha
        RET
       
IMPRIME:               
        XOR si,si             ;zera o vetor si a fim de acionar a posição inicial do vetor TEXTO
LOOP_IMPRIME:
        MOV al,TEXTO[si]     ;é necessário colocar em al para comparar seu conteúdo
        CMP al,'$'             ;compara determinado elemento do vetor TEXTO com o caractere $
        JE FINAL_IMPRIME
        MOV ah,02h             ;função DOS para imprimir uma string
        MOV dl,TEXTO[si]     ;string a ser impressa, deve ser colcada em dl
        INT 21h
        INC si                 ;incrementa si para continuar o loop
        JMP LOOP_IMPRIME       
FINAL_IMPRIME:
        RET
       
ENTER1:                     ;Forca o Enter
        PUSH AX             ;Guarda AX na pilha
        MOV DL,0DH          ;Passa para DL o caractere "Retorno de Carro"
          MOV AH,2h           ;Função 2h para imprimir um caracter
          INT 21h             ;Imprime o caracter que está em DL 
        MOV DL,0AH           ;Passa para DL o caractere "Line Feed"
          MOV AH,2h           ;Função 2h para imprimir um caracter
          INT 21h             ;Imprime o caracter que está em DL
        POP AX              ;DEVOLVE VALOR DE AX
        RET                    ;RETORNA PRA ONDE FOI CHAMADO

BACKSPACE:                    ;Forca o BACKSPACE
          MOV DL,32            ;Copia 32 decimal para DL o equivalente a ESPAÇO
          MOV AH,2h           ;Função 2h para imprimir um caracter
          INT 21h             ;Imprime o caracter que está em DL
          MOV DL,08h              ;Copia 08 hexa para DL o equivalente ao retorno de carro
          MOV AH,2h           ;Função 2h para imprimir um caracter
          INT 21h             ;Imprime o caracter que está em DL
           RET                 ;Retorna o controle ao procedimento que o chamou

COMMENT*------------------------------------------------------------------------------------
- Rotinas para salavar o vetor TEXTO em um arquivo com extensão txt
--------------------------------------------------------------------------------------------*                       

SALVAR:
        mov ah,3ch                        ; cria o arquivo
        mov cx,0                        ; 0 = arquivo normal
        mov dx,OFFSET arquivotexto        ; nome e ext. do arquivo na string
        int 21h
   
ABREPARAGRAVAR:           
        mov ah,3dh                ; função para abrir um arquivo
        mov al,1h                ; arquivo para escrita
        lea dx,arquivotexto        ; abre o arquivo
        int 21h
        mov AUX1,ax                ; salva o handle
   
ESCREVE:               
        mov bx,AUX1            ; grava randle no bx
        mov dx,OFFSET texto        ; pega o texto
        mov ah,40h                ; função para escrever a string no arquivo
        mov cx,si                ; quantidade de bytes a gravar,
        int 21h                    ; o tamanho do vetor é o tamanho de SI

TUDOCERTO:               
        call ENTER1
        lea dx,SALVOU    ; exibe a mensagem de arquivo salvo
        mov ah,9
        int 21h
        call ENTER1
        jmp FIM_SALVA

FIM_SALVA:               
        mov bx,AUX1        ; handle associado
        mov ah,3eh        ; função que fecha um arquivo
        int 21h
        jmp FIM            ; sai do programa
   
COMMENT*------------------------------------------------------------------------------------
- Abre um arquivo exitente para leitura
--------------------------------------------------------------------------------------------*   

CARREGAR:               
        call LIMPATELA
        mov dx,offset arquivotexto    ; offset do arquivo em 0d
        mov al,2                    ; leitura e escrita
        mov ah,3dh                    ; abre o arquivo
        int 21h
        mov AUX1,ax                    ; guarda o handle

IMPRIME_ARQUIVO:               
        mov ah,3fh            ; le do arquivo
        lea    dx,BUFFER2        ; endereço do data buffer
        mov cx,1            ; le 1 byte
        mov bx,AUX1            ; pega o handle do arquivo
        int 21h
        cmp ax,cx            ; end of file?
        jne SAIDOARQUIVO
        mov al,BUFFER2        ; pega o caracter lido
        mov texto[si],al
        inc si
        call IMPRIMITELA
        jmp IMPRIME_ARQUIVO

IMPRIMITELA:                   
        mov ah,2            ; prepara para exibir o caracter na tela
        mov dl,al
        int 21h
        ret

SAIDOARQUIVO:               
        mov bx,AUX1
        mov ah,3eh            ; fecha o arquivo
        int 21h
        jmp LOOP_ESC        ; Vai para a função de descrever
   
   
FIM:
        MOV    ah,4Ch             ; move valor 4ch para o registrador AH (encerra programa)
        INT    21h

END   INICIO                ; Finaliza o código do programa