Curso Fudeba de ASM

 


Aula 3: Trabalhando com o que temos.

 

   Nesta aula vamos fazer algumas coisas diferentes... Primeiramente vamos dar uma olhada em como podemos tornar a nossa vida mais simples na programação Assembly para o MSX (que, convenhamos, é algo muito mais útil que uma programação Assembly Z80 pura) com o material que temos, que é o M80/L80 para PC e o BrMSX.

   Também vamos aprender algumas brincadeiras novas com o nosso já bem estudado programinha, e não vamos acrescentar nenhuma nova funcionalidade a ele por enquanto: vamos apenas melhorar sua estrutura, tornando-o mais "adequado", digamos assim.

   Antes disso, vamos dar uma olhadinha no que vimos na ultima aula, que já faz um tempinho, visto que tive uns probleminhas de saúde aí no meio do caminho que me deixaram mais de 15 dias de cama.

   Na aula passada estendemos o nosso programa para apresentar informações na tela de uma forma um pouco mais padronizada, como é feito pela maioria dos programas para MSX-DOS (CP/M). Para isso, usamos sucessivas chamadas à função STROUT do BDOS. Como isso começou a tornar o programa 'meio confuso', foi introduzida a técnica de comentários por blocos, de forma a deixar o programa um pouco mais 'legível'.

   Ao colocar mais informações na tela, aprendemos a lidar com alguns caracteres de controle como o Carriage Return (CR, 13) e o Line Feed (LF, 10), que nos permite escolher um pouco melhor qual o posicionamento que queremos dar ao texto na tela. Depois desse processo, aprendemos como usar a função CONIN para receber uma entrada do usuário, aprendemos como guarda-la na memória e como usar a função CONOUT para colocar o caractere desta tecla novamente na tela. No meio do caminho deste aprendizado topamos com um imprevisto, que foi o fato de a função STROUT sumariamente sumir com o resultado que havíamos obtido com a função CONIN, problema que foi resolvido guardando-se a informação na memória logo após usarmos a função CONIN e antes de usar a função STROUT. Ao recuperarmos o valor da memória, topamos novamente com um problema: precisávamos do valor no registrador E é devido a uma limitação do Z80 (que é a de só podermos usar o registrador A como 'cola' para escrever ou ler dados que estão na memória) acabamos tendo que descobrir uma das formas de se lidar com isso, trocando dados entre os registradores A e E, aprendendo neste processo todo ainda algumas pequenas técnicas de debug (knock-out, o processo de sair removendo partes do programa e ver se o que foi removido sumiu com o que deveria sumir e se o problema sumiu junto).

   Bem, vamos aos tópicos da aula de hoje...

   Usando o BrMSX para acelerar o desenvolvimento
 

   Com as duas primeiras aulas vocês devem ter observado que, realmente, o Assembly não é um bicho de sete cabeças, apesar de ser meio chatinho, por ser detalhista. No entanto, uma coisa que deve ter incomodado bastante a vocês (a mim incomodou) foi o fato de termos de assemblar-no-PC,-copiarmos-no-disquete-e-levar-para-o-MSX. Isso é aborrecedor! Contra isso teríamos a alternativa de assemblar direto no MSX, usando a versão M80/L80 do MSX, mas contra isso temos que o MSX é muito mais lento para assemblar, e os editores de texto do MSX conseguem, em sua maioria, ser piores (ou mais lentos ou com menos recursos) que o próprio Notepad.

   O que fazer então? Porque não podemos fazer exatamente como no Basic, que escrevemos e rodamos?

   Bem, se você escrevessem em linguagem de maquina (aquele monte de numerozinhos em base hexadecimal) você efetivamente teria como executar o programa diretamente, mas adianto a você que isso é extremamente pouco pratico, principalmente no que se refere à variáveis e alguns outros detalhes. Então... não podemos escapar muito da rotina de assemblar antes de testar o programa (vocês vão ver que o Assemblador traz algumas vantagens extras nas próximas aulas), mas a gente pode, se não eliminar a peregrinação ao MSX, diminui-la. Mas como? Com o BrMSX.

   Antes de mais nada, vá no seu diretório "\ASMMSX" e crie dentro dele o seguinte diretório: BRMSX. Você deverá ter então:

\ASMMSX
[arquivos das aulas anteriores]
\ASMMSX\BRMSX

   E dentro deste \ASMMSX\BRMSX descomprima o BrMSX, que você encontra na pagina do Ricardo Bittencourt ( http://www.lsi.usp.br/~ricardo/brmsx.htm ou http://www.lsi.usp.br/~ricardo/brmsx206.zip diretamente ) e também crie, dentro deste diretório \ASMMSX\BRMSX o diretório: TESTE (\ASMMSX\BRMSX\TESTE ).
   Você vai precisar de dois arquivos do MSXDOS: MSXDOS.SYS e COMMAND.COM. Coloque-os dentro deste diretório ( \ASMMSX\BRMSX\TESTE ).
   Mude para o diretório das aulas anteriores com

CD\ASMMSX [enter]

e depois copie o arquivo da aula anterior para este novo diretório:

COPY PROG2.COM .\BRMSX\TESTE

   Com isso, tudo que você precisa para rodar o seu programa já está no diretório \ASMMSX\BRMSX\TESTE . Agora vamos aprender a executar isso usando o BrMSX, o que é muito simples... mude para o diretório do BrMSX:

CD BRMSX

e comande:

BRMSX -mount teste

   E você observará milagrosamente que o BrMSX já entrou com um MSX-DOS, e se você digitar DIR verá que os arquivos existentes neste "disquete virtual" são exatamente os arquivos que estavam no diretório:

\ASMMSX\BRMSX\TESTE

Para executar seu programa no BrMSX, a partir deste prompt do MSXDOS, basta você digitar:

PROG2 [enter]

   Garanto que funciona. Para sair e voltar ao MS-DOS (ou ao seu Windows), digite F10 e depois pressione Q. Quando você pressionar F10 verá uma tela cheia de números e uns dados em Assembly e outros.
   Essa tela é chamada FuDebug e é a melhor coisa que existe no BrMSX para quem quer programar Assembly. Daqui algumas aulas nos vamos utilizar extensivamente o BrMSX exatamente para tirarmos proveito do FuDebug... assim, é bom que você já vá se acostumando a executar seus programas no BrMSX.

   Você pode automatizar esse procedimento todo criando arquivos de lote no MS-DOS/Windows, e tudo ficará bem automático, mas lembre-se que é importante executar seu programa no MSX real e testa-lo com alguma freqüência... simplesmente para conferir se as coisas estão andando como deviam. Em geral estarão, mas não custa nada dar uma verificada (jamais libere uma versão nova do seu software para MSX sem te-lo executado antes no MSX. Você pode ter alguma surpresa bem desagradável).

   Aprenda bem esse procedimento de executar os programas no BrMSX.
   Futuramente irei comentar sobre utilização de funções do BrMSX mais aprofundadas, e é importante que você já esteja familiarizado com a execução do seu software dentro do ambiente do BrMSX, de forma que você possa se preocupar somente com a explicação da nova função, e não com o procedimento de como carregar o software pelo BrMSX.

   Otimizando nosso programa

   Bem, agora já nos livramos de ter que, a cada compilação, jogar num disquete, levar até o MSX e executar para então ver que não funciona etc. e tal... Agora já podemos trabalhar um pouco mais confortavelmente no PC, usando o BrMSX.
Vamos ver como podemos dar uma otimizada no nosso programa da aula passada... que no fim, ficou da seguinte forma:

--- Cortar Aqui ---
BDOS    EQU     5

CONIN   EQU     1
CONOUT  EQU     2
STROUT  EQU     9

START:
        ; Mostra nome do programa
        LD      DE,NOMEDOPRG            ; Indica texto do nome do programa
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.

        ; Mostra nome do programador
        LD      DE,AUTOR                ; Indica texto do nome do autor
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.

        ; Mostra a pergunta
        LD      DE,PERGU1               ; Indica texto da pergunta
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.

        ; Espera tecla ser pressionada e coloca seu valor em A
        LD      C,CONIN                 ; Indica a função que pega uma tecla
        CALL    BDOS                    ; Chama BDOS
        LD      (VAR1),A                ; Grava o valor da tecla na MEMORIA.

        ; Mostra a resposta
        LD      DE,RESP1                ; Indica texto da resposta
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.
        LD      A,(VAR1)                ; Copia para A o conteúdo de VAR1
        LD      E,A                     ; Copia para E o conteúdo de A
        LD      C,CONOUT                ; Indica a função exibe um caractere na tela
        CALL    BDOS                    ; Chama BDOS

        JP      0                       ; Volta ao MSX-DOS

NOMEDOPRG:      DB      'Programa 2 - Conversando com o usuario',13,10,'$'
AUTOR:          DB      '  Por Daniel Caetano',13,10,10,'$'
PERGU1:         DB      '  Pressione alguma tecla: $'
RESP1:          DB      13,10,10,'  A tecla pressionada foi: $'
VAR1:           DB      0

        END
--- Cortar Aqui ---

   Vocês devem ter reparado uma certa repetição, ao menos na parte de mostrar algum texto:

        ; Mostra nome do programa
        LD      DE,NOMEDOPRG            ; Indica texto do nome do programa
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.
        ; Mostra nome do programador
        LD      DE,AUTOR                ; Indica texto do nome do autor
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.
        ; Mostra a pergunta
        LD      DE,PERGU1               ; Indica texto da pergunta
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.
        ; Mostra a resposta
        LD      DE,RESP1                ; Indica texto da resposta
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.

   Preste atenção na padronização. Podemos dizer que em todas essas chamadas, tem uma parte que não muda jamais:

        ; Comentário
        LD      DE,xxxx                 ; Indica texto 
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.

   Como dá pra observar, apenas UM parâmetro muda numa seqüência inteira de instruções. Esse parâmetro é justamente o endereço do texto. Bem, e se a gente transformasse esse bloco todo em algo que pudesse ser chamado com apenas um comando?
   É o que nos vamos aprender a fazer agora... vamos criar uma função NOSSA, nossa primeira função. A primeira coisa que precisamos definir em uma função é o seu nome. Essa função faz exatamente o que? Mostra um texto, não é? Que tal darmos o nome MOSTRATXT para ela? Numa primeira etapa nossa função fica assim:

MOSTRATXT

   Mas... isso vai dar erro, seguramente, no nosso assemblador. Precisamos dar um jeito de dizer a ele que raios significa esse "MOSTRATXT". E como fazemos isso? Dizendo a ele que ele que este é um ponto de entrada, ou, de forma mais simples, que esta é uma função. E como dizemos isso a ele?
   Usando o caractere ":" na frente do nome da função:

MOSTRATXT:

   Isso já vai passar, ao menos, no nosso assemblador. Bem, também é conveniente colocar alguns comentários no inicio da função, dizendo o que esta função faz:

;------
; MOSTRATXT - Função que mostra um texto cuja seqüência é terminada por '$'.
;------
MOSTRATXT:

   Já começou a ficar com uma aparência melhor, não? Bem, agora a gente pega e joga o nosso código dentro:

;------
; MOSTRATXT - Função que mostra um texto cuja seqüência é terminada por '$'.
;------
MOSTRATXT:
        ; Comentário
        LD      DE,xxxx                 ; Indica texto 
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.

   Bem, esse primeiro comentário pode ser suprimido, já que não acrescenta nada neste lugar (a função dele já é feita pela descrição da função).

;------
; MOSTRATXT - Função que mostra um texto cuja seqüência é terminada por '$'.
;------
MOSTRATXT:
        LD      DE,xxxx                 ; Indica texto 
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.

   Alem disso, o LD DE,xxxx é algo que muda sempre, então também deve ser retirado daí, e é um valor que já deve vir pronto de fora. Ao suprimirmos essa linha, devemos acrescentar um comentário na descrição da função, dizendo que o texto deve estar indicado em DE, e teremos como resultado:

;------
; MOSTRATXT - Função que mostra um texto cuja seqüência é terminada por '$'.
;    Entrada: DE - Aponta para seqüência a ser mostrada, terminada por '$'
;------
MOSTRATXT:
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.

   E pronto, nossa função está pronta. A questão é: onde vamos colocar isso em nosso programa? Um bom lugar é entre o fim do nosso programa (JP 0) e as variáveis.
Vamos fazer isso?

--- Cortar Aqui ---
BDOS    EQU     5

CONIN   EQU     1
CONOUT  EQU     2
STROUT  EQU     9

START:
        ; Mostra nome do programa
        LD      DE,NOMEDOPRG           ; Indica texto do nome do programa
        LD      C,STROUT               ; Indica função de mostrar texto do BDOS
        CALL    BDOS                   ; Manda o BDOS executar.

        ; Mostra nome do programador
        LD      DE,AUTOR               ; Indica texto do nome do autor
        LD      C,STROUT               ; Indica função de mostrar texto do BDOS
        CALL    BDOS                   ; Manda o BDOS executar.

        ; Mostra a pergunta
        LD      DE,PERGU1              ; Indica texto da pergunta
        LD      C,STROUT               ; Indica função de mostrar texto do BDOS
        CALL    BDOS                   ; Manda o BDOS executar.

        ; Espera tecla ser pressionada e coloca seu valor em A
        LD      C,CONIN                ; Indica a função que pega uma tecla
        CALL    BDOS                   ; Chama BDOS
        LD      (VAR1),A               ; Grava o valor da tecla na MEMORIA.

        ; Mostra a resposta
        LD      DE,RESP1               ; Indica texto da resposta
        LD      C,STROUT               ; Indica função de mostrar texto do BDOS
        CALL    BDOS                   ; Manda o BDOS executar.
        LD      A,(VAR1)               ; Copia para A o conteúdo de VAR1
        LD      E,A                    ; Copia para E o conteúdo de A
        LD      C,CONOUT               ; Indica a função exibe um caractere na tela
        CALL    BDOS                   ; Chama BDOS

        JP      0                      ; Volta ao MSX-DOS


;------
; MOSTRATXT - Função que mostra um texto cuja seqüência é terminada por '$'.
;    Entrada: DE - Aponta para seqüência a ser mostrada, terminada por '$'
;------
MOSTRATXT:
        LD      C,STROUT               ; Indica função de mostrar texto do BDOS
        CALL    BDOS                   ; Manda o BDOS executar.


NOMEDOPRG:      DB      'Programa 3 - Otimizando a estruturá,13,10,'$'
AUTOR:          DB      '  Por Daniel Caetano',13,10,10,'$'
PERGU1:         DB      '  Pressione alguma tecla: $'
RESP1:          DB      13,10,10,'  A tecla pressionada foi: $'
VAR1:           DB      0

        END
--- Cortar Aqui ---

   Pronto! Nosso programa já tem uma função agora. Experimente salvar esse texto como PROG3.MAC e assembla-lo com o já manjado CL80 PROG3 e depois executa-lo no BrMSX como explicado no inicio desta aula. Funcionou, não? Claro que sim, mas se você observar, não ganhamos nada com isso. Na verdade, perdemos. Nosso programa ficou maior e mais confuso de ler.
Mas isso só aconteceu devido ao fato de que não acrescentamos a função em nosso programa, mas ainda não a utilizamos! Para que nosso programa ganhe benefícios desta função, precisamos modificar as partes dele para que estas se utilizem da função. E como fazemos isso? Bem, peguemos cada parte do programa que se assemelhe a:

        ; Mostra nome do programa
        LD      DE,NOMEDOPRG            ; Indica texto do nome do programa
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.

  E faca com que fique na forma:

        ; Mostra nome do programa
        LD      DE,NOMEDOPRG            ; Indica texto do nome do programa
        CALL    MOSTRATXT               ; Mostra texto

   O que indica que usamos a instrução CALL para chamar a nossa função.
   Quando o Z80 for executar esses comandos, o que ele vai fazer? Ele vai carregar DE com NOMEDOPRG:

        LD      DE,NOMEDOPRG

   Depois ele vai pular para a função MOSTRATXT, onde ele vai encontrar uma instrução dizendo para ele carregar C com STROUT:

        LD      C,STROUT

   E finalmente vai mandar o BDOS executar a nossa função:

        CALL    BDOS

   Ou seja, no fim das contar, para o Z80 o programa continuou o mesmo, a menos do fato as instruções agora estão 'espalhadas' pelo programa. Se mudarmos todas as partes que estão na forma:

        ; Comentário
        LD      DE,xxxx                 ; Indica texto 
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.

para

        ; Comentário
        LD      DE,xxxx                 ; Indica texto 
        CALL    MOSTRATXT               ; Mostra texto

   Ficaremos com o programa assim:

--- Cortar Aqui ---
BDOS    EQU     5

CONIN   EQU     1
CONOUT  EQU     2
STROUT  EQU     9

START:
        ; Mostra nome do programa
        LD      DE,NOMEDOPRG            ; Indica texto do nome do programa
        CALL    MOSTRATXT               ; Mostra texto

        ; Mostra nome do programador
        LD      DE,AUTOR                ; Indica texto do nome do autor
        CALL    MOSTRATXT               ; Mostra texto

        ; Mostra a pergunta
        LD      DE,PERGU1               ; Indica texto da pergunta
        CALL    MOSTRATXT               ; Mostra texto

        ; Espera tecla ser pressionada e coloca seu valor em A
        LD      C,CONIN                 ; Indica a função que pega uma tecla
        CALL    BDOS                    ; Chama BDOS
        LD      (VAR1),A                ; Grava o valor da tecla na MEMORIA.

        ; Mostra a resposta
        LD      DE,RESP1                ; Indica texto da resposta
        CALL    MOSTRATXT               ; Mostra texto
        LD      A,(VAR1)                ; Copia para A o conteúdo de VAR1
        LD      E,A                     ; Copia para E o conteúdo de A
        LD      C,CONOUT                ; Indica a função exibe um caractere na tela
        CALL    BDOS                    ; Chama BDOS

        JP      0                       ; Volta ao MSX-DOS


;------
; MOSTRATXT - Função que mostra um texto cuja seqüência é terminada por '$'.
;    Entrada: DE - Aponta para seqüência a ser mostrada, terminada por '$'
;------
MOSTRATXT:
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.


NOMEDOPRG:      DB      'Programa 3 - Otimizando a estruturá,13,10,'$'
AUTOR:          DB      '  Por Daniel Caetano',13,10,10,'$'
PERGU1:         DB      '  Pressione alguma tecla: $'
RESP1:          DB      13,10,10,'  A tecla pressionada foi: $'
VAR1:           DB      0

        END
--- Cortar Aqui ---

   E o programa já ficou mais limpo. No entanto, percebemos que aqueles comentários de blocos tão pertinentes anteriormente agora estão mais poluindo o nosso programa do que ajudando. Podemos modifica-los de forma que continuem explicando o que está acontecendo, sem que fiquem poluindo tudo. Isso pode ser conseguido assim:

--- Cortar Aqui ---
BDOS    EQU     5

CONIN   EQU     1
CONOUT  EQU     2
STROUT  EQU     9

START:
        ; Mostra informações do programa e faz pergunta
        LD      DE,NOMEDOPRG            ; Indica texto do nome do programa
        CALL    MOSTRATXT               ; Mostra texto
        LD      DE,AUTOR                ; Indica texto do nome do autor
        CALL    MOSTRATXT               ; Mostra texto
        LD      DE,PERGU1               ; Indica texto da pergunta
        CALL    MOSTRATXT               ; Mostra texto

        ; Espera tecla ser pressionada e coloca seu valor em A
        LD      C,CONIN                 ; Indica a função que pega uma tecla
        CALL    BDOS                    ; Chama BDOS
        LD      (VAR1),A                ; Grava o valor da tecla na MEMORIA.

        ; Mostra a resposta
        LD      DE,RESP1                ; Indica texto da resposta
        CALL    MOSTRATXT               ; Mostra texto
        LD      A,(VAR1)                ; Copia para A o conteúdo de VAR1
        LD      E,A                     ; Copia para E o conteúdo de A
        LD      C,CONOUT                ; Indica a função exibe um caractere na tela
        CALL    BDOS                    ; Chama BDOS

        JP      0                       ; Volta ao MSX-DOS


;------
; MOSTRATXT - Função que mostra um texto cuja seqüência é terminada por '$'.
;    Entrada: DE - Aponta para seqüência a ser mostrada, terminada por '$'
;------
MOSTRATXT:
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.

NOMEDOPRG:      DB      'Programa 3 - Otimizando a estruturá,13,10,'$'
AUTOR:          DB      '  Por Daniel Caetano',13,10,10,'$'
PERGU1:         DB      '  Pressione alguma tecla: $'
RESP1:          DB      13,10,10,'  A tecla pressionada foi: $'
VAR1:           DB      0

        END
--- Cortar Aqui ---

   Uau! Bem mais limpo, não? Sim. Experimente assemblar esse programa e executa-lo, tanto no BrMSX quanto no MSX real. Não funcionou?

   Bem, em ambos os casos ele deve ter mostrado o nome do programa, uma seqüência de lixo e o computador deve ter travado ou voltado ao MSX-DOS. Por que isso aconteceu? Vamos seguir o programa passo a passo e ver onde está o erro? Bem, o programa começa com:

START:
        ; Mostra informações do programa e faz pergunta
        LD      DE,NOMEDOPRG            ; Indica texto do nome do programa

   Jóia... até aqui o programa carregou a posição do texto em DE.

        CALL    MOSTRATXT               ; Mostra texto

   Agora ele chama a nossa função... vamos até lá?

MOSTRATXT:
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS

   Carregou o valor de STROUT em C...

        CALL    BDOS                    ; Manda o BDOS executar.

   Chamou o BDOS... e ao voltar...

NOMEDOPRG:      DB      'Programa 3 - Otimizando a estruturá,13,10,'$'

   Epa! Tem alguma coisa errada aí. Não era para ele seguir por esse caminho, e sim voltar lá para cima e continuar com:

         LD      DE,AUTOR                ; Indica texto do nome do autor

Não é mesmo? Sim, é... mas a gente precisa avisar o Z80 quando é pra voltar de um CALL. O comando que usamos para isso é o RET (RETurn, de retorne). Assim, precisamos, sempre que fazemos uma função, criar a instrução RET no fim da função. Nossa função deve então ser modificada para ficar assim:

;------
; MOSTRATXT - Função que mostra um texto cuja seqüência é terminada por '$'.
;    Entrada: DE - Aponta para seqüência a ser mostrada, terminada por '$'
;------
MOSTRATXT:
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.
        RET                             ; Retorna

   E o nosso programa fica assim:

--- Cortar Aqui ---
BDOS    EQU     5

CONIN   EQU     1
CONOUT  EQU     2
STROUT  EQU     9

START:
        ; Mostra informações do programa e faz pergunta
        LD      DE,NOMEDOPRG            ; Indica texto do nome do programa
        CALL    MOSTRATXT               ; Mostra texto
        LD      DE,AUTOR                ; Indica texto do nome do autor
        CALL    MOSTRATXT               ; Mostra texto
        LD      DE,PERGU1               ; Indica texto da pergunta
        CALL    MOSTRATXT               ; Mostra texto

        ; Espera tecla ser pressionada e coloca seu valor em A
        LD      C,CONIN                 ; Indica a função que pega uma tecla
        CALL    BDOS                    ; Chama BDOS
        LD      (VAR1),A                ; Grava o valor da tecla na MEMORIA.

        ; Mostra a resposta
        LD      DE,RESP1                ; Indica texto da resposta
        CALL    MOSTRATXT               ; Mostra texto
        LD      A,(VAR1)                ; Copia para A o conteúdo de VAR1
        LD      E,A                     ; Copia para E o conteúdo de A
        LD      C,CONOUT                ; Indica a função exibe um caractere na tela
        CALL    BDOS                    ; Chama BDOS

        JP      0                       ; Volta ao MSX-DOS


;------
; MOSTRATXT - Função que mostra um texto cuja seqüência é terminada por '$'.
;    Entrada: DE - Aponta para seqüência a ser mostrada, terminada por '$'
;------
MOSTRATXT:
        LD      C,STROUT                ; Indica função de mostrar texto do BDOS
        CALL    BDOS                    ; Manda o BDOS executar.
        RET                             ; Retorna

NOMEDOPRG:      DB      'Programa 3 - Otimizando a estruturá,13,10,'$'
AUTOR:          DB      '  Por Daniel Caetano',13,10,10,'$'
PERGU1:         DB      '  Pressione alguma tecla: $'
RESP1:          DB      13,10,10,'  A tecla pressionada foi: $'
VAR1:           DB      0

        END
--- Cortar Aqui ---

   Assemblando esse código e executando-o no MSX real ou no BrMSX, você verá que agora ele funciona bem, ficou menor e mais fácil de ler. O ganho é maior quanto mais vezes a repetição aparecer e maior for o trecho repetido.
   Neste exemplo o ganho é até pequeno, mas este tipo de otimização, em um programa complexo, pode ser a diferença entre ele ter um tamanho ou ser muito maior, podendo chegar a ser seis, sete, n vezes maior.

   Na aula que vem vamos aprender a usar o BrMSX para achar falhas como essa falta do "RET" ao invés de ficar lendo o código até encontra-la por nos mesmos, e também vamos aprender algo um pouco mais complicado, que é como otimizar ainda mais o programa, transformando isso:

        LD      DE,NOMEDOPRG            ; Indica texto do nome do programa
        CALL    MOSTRATXT               ; Mostra texto
        LD      DE,AUTOR                ; Indica texto do nome do autor
        CALL    MOSTRATXT               ; Mostra texto
        LD      DE,PERGU1               ; Indica texto da pergunta
        CALL    MOSTRATXT               ; Mostra texto

   Em algo mais otimizado, visto que você deve ter observado que isso segue uma lógica bem explicita, principalmente se você observar que os valores variáveis (NOMEDOPRG, AUTOR e PERGU1) estão assim na memória:

NOMEDOPRG:      DB      'Programa 3 - Otimizando a estruturá,13,10,'$'
AUTOR:          DB      '  Por Daniel Caetano',13,10,10,'$'
PERGU1:         DB      '  Pressione alguma tecla: $'

   Até lá, espero que mais rapidamente, finalmente livre das enfermidades.
   Quaisquer duvidas, enviem para a lista, eu ou qualquer um dos programadores da lista responderão tão breve quanto possível.

Abraços,

Daniel Caetano.

PS: Sugestões e comentários são bem-vindos. (^=