CAPÍTULO 7: EXEMPLOS DE PROGRAMAS
Conteúdo:
7.1.Exemplos de Programas com Debug 7.2.Exemplos de Programas com TASM
--------------- // ---------------
7.1.Exemplos de Programas com Debug
Nesta seção forneceremos alguns programas feitos no debug do DOS. Você pode executar cada programa assembly usando o comando "g" (go), para ver o que cada programa faz.
Procedimento
Primeiro passo
Carregar o programa exemplo
Por exemplo:
C:\>debug -n one.com -l -u 100 109 0D80:0100 B80600 MOV AX,0006 0D80:0103 BB0400 MOV BX,0004 0D80:0106 01D8 ADD AX,BX 0D80:0108 CD20 INT 20 -
Nota:
-n one.com
Dar nome ao programa a ser carregado
-l
Carregá-lo
-u 100 109
Desmontar o código do endereço inicial ao final especificado
Segundo passo
Digite o comando g Por exemplo:
-g
Program terminated normally -
Exemplos de programas no Debug
Primeiro exemplo
-a0100 297D:0100 MOV AX,0006 ;Põe o valor 0006 no registrador AX 297D:0103 MOV BX,0004 ;Põe o valor 0004 no registrador BX 297D:0106 ADD AX,BX ;Adiciona BX ao conteúdo de AX 297D:0108 INT 20 ;Finaliza o Programa
A única coisa que este programa faz é salvar dois valores em dois registradores e adicionar o valor de um ao outro.
Segundo exemplo
- a100 0C1B:0100 jmp 125 ;Salta para o endereço 125h 0C1B:0102 [Enter] - e 102 'Hello, How are you ?' 0d 0a '$' - a125 0C1B:0125 MOV DX,0102 ;Copia a string para registrador DX 0C1B:0128 MOV CX,000F ;Quantas vezes a string ser mostrada 0C1B:012B MOV AH,09 ;Copia o valor 09 para registrador AH 0C1B:012D INT 21 ;Mostra a string 0C1B:012F DEC CX ;Subtrai 1 de CX 0C1B:0130 JCXZ 0134 ;Se CX igual a 0 salta para o endereço 0134 0C1B:0132 JMP 012D ;Salta ao endereço 012D 0C1B:0134 INT 20 ;Finaliza o programa
Este programa mostra 15 vezes na tela a string de caracteres.
Terceiro exemplo
-a100 297D:0100 MOV AH,01 ;Função para mudar o cursor 297D:0102 MOV CX,0007 ;Formata o cursor 297D:0105 INT 10 ;Chama interrupção do BIOS 297D:0107 INT 20 ;Finaliza o programa
Este programa muda o formato do cursor.
Quarto exemplo
-a100 297D:0100 MOV AH,01 ;Função 1 (lê caractere do teclado) 297D:0102 INT 21 ;Chama interrupção do DOS 297D:0104 CMP AL,0D ;Compara se o caractere lido é um ENTER 297D:0106 JNZ 0100 ;Se não é, lê um outro caractere 297D:0108 MOV AH,02 ;Função 2 (escreve um caractere na tela) 297D:010A MOV DL,AL ;Character to write on AL 297D:010C INT 21 ;Chama interrupção do DOS 297D:010E INT 20 ;Finaliza o programa
Este programa usa a interrupção 21h do DOS. Usa duas funções da mesma: a primeira lê um caractere do teclado (função 1) e a segundo escreve um caractere na tela. O programa lê caracteres do teclado até encontrar um ENTER.
Quinto exemplo
-a100 297D:0100 MOV AH,02 ;Função 2 (escreve um caractere na tela) 297D:0102 MOV CX,0008 ;Põe o valor 0008 no registrador CX 297D:0105 MOV DL,00 ;Põe o valor 00 no registrador DL 297D:0107 RCL BL,1 ;Rotaciona o byte em BL um bit para a esquerda 297D:0109 ADC DL,30 ;Converte o registrador de flag para 1 297D:010C INT 21 ;Chama interrupção do DOS 297D:010E LOOP 0105 ;Salta se CX > 0 para o endereço 0105 297D:0110 INT 20 ;Finaliza o programa
Este programa mostra na tela um número binário através de um ciclo condicional (LOOP) usando a rotação do byte.
Sexto exemplo
-a100 297D:0100 MOV AH,02 ;Função 2 (escreve um caractere na tela) 297D:0102 MOV DL,BL ;Põe o valor de BL em DL 297D:0104 ADD DL,30 ;Adiciona o valor 30 a DL 297D:0107 CMP DL,3A ;Compara o valor 3A com o conteúdo de DL sem afetá-lo ;seu valor apenas modifica o estado do flag de carry 297D:010A JL 010F ;salta ao endereço 010f, se for menor 297D:010C ADD DL,07 ;Adiciona o valor 07 a DL 297D:010F INT 21 ;Chama interrupção do DOS 297D:0111 INT 20 ;Finaliza o programa
Este programa imprime um valor zero em dígitos hexadecimais.
Sétimo exemplo
-a100 297D:0100 MOV AH,02 ;Função 2 (escreve um caractere na tela) 297D:0102 MOV DL,BL ;Põe o valor de BL em DL 297D:0104 AND DL,0F ;Transporta fazendo AND dos números bit a bit 297D:0107 ADD DL,30 ;Adiciona 30 a Dl 297D:010A CMP DL,3A ;Compara Dl com 3A 297D:010D JL 0112 ;Salta ao endereço 0112, se menor 297D:010F ADD DL,07 ;Adiciona 07 a DL 297D:0112 INT 21 ;Chama interrupção do DOS 297D:0114 INT 20 ;Finaliza o programa
Este programa é usado para imprimir dois dígitos hexadecimais.
Oitavo exemplo
-a100 297D:0100 MOV AH,02 ;Função 2 (escreve um caractere na tela) 297D:0102 MOV DL,BL ;Põe o valor de BL em DL 297D:0104 MOV CL,04 ;Põe o valor 04 em CL 297D:0106 SHR DL,CL ;Desloca os 4 bits mais altos do número ao nibble mais á direita 297D:0108 ADD DL,30 ;Adiciona 30 a DL 297D:010B CMP DL,3A ;Compara Dl com 3A 297D:010E JL 0113 ;Salta ao endereço 0113, se menor 297D:0110 ADD DL,07 ;Adiciona 07 a DL 297D:0113 INT 21 ;Chama interrupção do DOS 297D:0115 INT 20 ;Finaliza o programa
Este programa imprime o primeiro de dois dígitos hexadecimais.
Nono exemplo
-a100 297D:0100 MOV AH,02 ;Função 2 (escreve um caractere na tela) 297D:0102 MOV DL,BL ;Põe o valor de BL em DL 297D:0104 MOV CL,04 ;Põe o valor 04 em CL 297D:0106 SHR DL,CL ;Desloca os 4 bits mais altos do número ao nibble mais á direita 297D:0108 ADD DL,30 ;Adiciona 30 a DL 297D:010B CMP DL,3A ;Compara Dl com 3A 297D:010E JL 0113 ;Salta ao endereço 0113, se menor 297D:0110 ADD DL,07 ;Adiciona 07 a DL 297D:0113 INT 21 ;Chama interrupçãoo do DOS 297D:0115 MOV DL,BL ;Põe o valor de BL em DL 297D:0117 AND DL,0F ;Transporta fazendo AND dos números bit a bit 297D:011A ADD DL,30 ;Adiciona 30 a DL 297D:011D CMP DL,3A ;Compara Dl com 3A 297D:0120 JL 0125 ;Salta ao endereço 0125, se menor 297D:0122 ADD DL,07 ;Adiciona 07 a DL 297D:0125 INT 21 ;Chama interrupção do DOS 297D:0127 INT 20 ;Finaliza o programa
Este programa imprime o segundo de dois dígitos hexadecimais.
Décimo exemplo
-a100 297D:0100 MOV AH,01 ;Função 1 (lê caractere do teclado) 297D:0102 INT 21 ;Chama interrupção do DOS 297D:0104 MOV DL,AL ;Põe o valor de AL em DL 297D:0106 SUB DL,30 ;Subtrai 30 de DL 297D:0109 CMP DL,09 ;Compara DL com 09 297D:010C JLE 0111 ;Salta ao endereço 0111, se menor ou igual 297D:010E SUB DL,07 ;Subtrai 07 de DL 297D:0111 MOV CL,04 ;Põe o valor 04 em CL 297D:0113 SHL DL,CL ;Insere zeros á direita 297D:0115 INT 21 ;Chama interrupção do DOS 297D:0117 SUB AL,30 ;Subtrai 30 de AL 297D:0119 CMP AL,09 ;Compara AL com 09 297D:011B JLE 011F ;Salta ao endereço 011f, se menor ou igual 297D:011D SUB AL,07 ;Subtrai 07 de AL 297D:011F ADD DL,AL ;Adiciona AL a DL 297D:0121 INT 20 ;Finaliza o programa
Este programa pode ler dois dígitos hexadecimais.
Décimo primeiro exemplo
-a100 297D:0100 CALL 0200 ;Chama um procedimento 297D:0103 INT 20 ;Finaliza o programa -a200 297D:0200 PUSH DX ;Põe o valor de DX na pilha 297D:0201 MOV AH,08 ;Função 8 297D:0203 INT 21 ;Chama interrupção do DOS 297D:0205 CMP AL,30 ;Compara AL com 30 297D:0207 JB 0203 ;Salta se CF é ativado ao endereço 0203 297D:0209 CMP AL,46 ;Compara AL com 46 297D:020B JA 0203 ;Salta ao endereço 0203, se diferente 297D:020D CMP AL,39 ;Compara AL com 39 297D:020F JA 021B ;Salta ao endereço 021B, se diferente 297D:0211 MOV AH,02 ;Função 2 (escreve um caractere na tela) 297D:0213 MOV DL,AL ;Põe o valor de AL em DL 297D:0215 INT 21 ;Chama interrupção do DOS 297D:0217 SUB AL,30 ;Subtrai 30 de AL 297D:0219 POP DX ;Extrai o valor de DX da pilha 297D:021A RET ;Retorna o controle ao programa principal 297D:021B CMP AL,41 ;Compara AL com 41 297D:021D JB 0203 ;Salta se CF é ativado ao endereço 0203 297D:021F MOV AH,02 ;Função 2 (escreve um caractere na tela) 297D:022 MOV DL,AL ;Põe o valor AL em DL 297D:0223 INT 21 ;Chama interrupção do DOS 297D:0225 SUB AL,37 ;Subtrai 37 de AL 297D:0227 POP DX ;Extrai o valor de DX da pilha 297D:0228 RET ;Retorna o controle ao programa principal
Este programa se mantém lendo caracteres até receber um que possa ser convertido para um número hexadecimal.
--------------- // ---------------
7.2.Exemplos de Programas com TASM
Nesta seção forneceremos a você vários exemplos de programas a serem montados fazendo uso do TASM da Borland.
Procedimento:
Para montá-los, siga os seguintes passos:
Primeiro passo
Montar o programa Por exemplo:
C:\>tasm one.asm Turbo Assembler Version 2.0 Copyright (c) 1988, 1990 Borland International Assembling file: one.asm Error messages: None Warning messages: None Passes: 1 Remaining memory: 471k
C:\>
Isto criará um programa objeto com o mesmo nome do fonte, neste caso: one.obj
Segundo passo
Criar o programa executável Por exemplo:
C:\>tlink one.obj Turbo Link Version 3.0 Copyright (c) 1987, 1990 Borland International
C:\> Isto cria o programa executável com o mesmo nome do objeto e com extensão diferente, one.exe
Terceiro passo
Rodar o programa executável. Basta digitar o nome do programa criado.
Exemplos de Programas Assembly
Primeiro exemplo
;nome do programa: one.asm ; .model small .stack .code mov AH,1h ;Função 1 do DOS Int 21h ;lê o caracter e returna o código ASCII ao registrador AL mov DL,AL ;move o código ASCII para o registrador DL sub DL,30h ;subtrai de 30h para converter a um dígito de 0 a 9 cmp DL,9h ;compara se o dígito está entre 0 e 9 jle digit1 ;se verdadeiro obtém o primeiro número (4 bits) sub DL,7h ;se falso, subtrai de 7h para converter a uma letra A-F digit1: mov CL,4h ;prepara para multiplicar por 16 shl DL,CL ;multiplica para converter dentro dos 4 bits mais altos int 21h ;obtém o próximo caracter sub AL,30h ;repete a operação de conversão cmp AL,9h ;compara o valor 9h com o conteúdo do registrador AL jle digit2 ;se verdadeiro, obtém o segundo dígito sub AL,7h ;se falso, subtrai de 7h digit2: add DL,AL ;adiciona o segundo dígito mov AH,4Ch ;função 4Ch do DOS (exit) Int 21h ;interrupção 21h End ;finaliza o programa
Este programa lê dois caracteres e os imprime na tela
Segundo exemplo
;nome do programa: two.asm .model small .stack .code PRINT_A_J PROC MOV DL,'A' ;move o character A para o registrador DL MOV CX,10 ;move o valor decimal 10 para o registrador CX ;este valor é usado para fazer laço com 10 interações PRINT_LOOP: CALL WRITE_CHAR ;Imprime o caracter em DL INC DL ;Incrementa o valor do registrador DL LOOP PRINT_LOOP ;Laço para imprimir 10 caracteres MOV AH,4Ch ;Função 4Ch, para sair ao DOS INT 21h ;Interrupção 21h PRINT_A_J ENDP ;Finaliza o procedimento
WRITE_CHAR PROC MOV AH,2h ;Função 2h, imprime caracter INT 21h ;Imprime o caracter que está em DL RET ;Retorna o controle ao procedimento que chamou WRITE_CHAR ENDP ;Finaliza o procedimento END PRINT_A_J ;Finaliza o programa
Este programa mostra os caracteres ABCDEFGHIJ na tela.
Terceiro exemplo
;nome do programa: three.asm .model small .STACK .code
TEST_WRITE_HEX PROC MOV DL,3Fh ;Move o valor 3Fh para o registrador DL CALL WRITE_HEX ;Chama a sub-rotina MOV AH,4CH ;Função 4Ch INT 21h ;Retorna o controle ao DOS TEST_WRITE_HEX ENDP ;Finaliza o procedimento
PUBLIC WRITE_HEX ;........................................................; ;Este procedimento converte para hexadecimal o byte ; ;armazenado no registrador DL e mostra o dígito ; ;Use:WRITE_HEX_DIGIT ; ;........................................................;
WRITE_HEX PROC PUSH CX ;coloca na pilha o valor do registrador CX PUSH DX ;coloca na pilha o valor do registrador DX MOV DH,DL ;move o valor do registrador DL para o registrador DH MOV CX,4 ;move o valor 4 para o registrador CX SHR DL,CL CALL WRITE_HEX_DIGIT ;mostra na tela o primeiro número hexadecimal MOV DL,DH ;move o valor do registrador DH para o registrador DL AND DL,0Fh CALL WRITE_HEX_DIGIT ;mostra na tela o segundo número hexadecimal POP DX ;retira da pilha o valor do registrador DX POP CX ;retira da pilha o valor do registrador CX RET ;Retorna o controle ao procedimento que chamou WRITE_HEX ENDP
PUBLIC WRITE_HEX_DIGIT ;......................................................................; ;Este procediento converte os 4 bits mais baixos do registrador DL ; ;para um número hexadecimal e o mostra na tela do computador ; ;Use: WRITE_CHAR ; ;......................................................................;
WRITE_HEX_DIGIT PROC PUSH DX ;coloca na pilha o valor de DX CMP DL,10 ;compara se o número de bits é menor do que 10 JAE HEX_LETTER ;se não, salta para HEX_LETER ADD DL,"0" ;se sim, converte para número JMP Short WRITE_DIGIT ;escreve o caracter HEX_LETTER: ADD DL,"A"-10 ;converte um caracter para hexadecimal WRITE_DIGIT: CALL WRITE_CHAR ;imprime o caracter na tela POP DX ;Retorna o valor inicial do registrador DX ;para o registrador DL RET ;Retorna o controle ao procedimento que chamou WRITE_HEX_DIGIT ENDP
PUBLIC WRITE_CHAR ;......................................................................; ;Este procedimento imprime um caracter na tela usando o D.O.S. ; ;......................................................................;
WRITE_CHAR PROC PUSH AX ;Coloca na pilha o valor do registarador AX MOV AH,2 ;Função 2h INT 21h ;Interrupção 21h POP AX ;Extrai da pilha o valor de AX RET ;Retorna o controle ao procedimento que chamou WRITE_CHAR ENDP
END TEST_WRITE_HEX ;Finaliza o programa
Quarto exemplo
;nome do programa: four.asm .model small .stack .code
TEST_WRITE_DECIMAL PROC MOV DX,12345 ;Move o valor decimal 12345 para o registrador DX CALL WRITE_DECIMAL ;Chama o procedimento MOV AH,4CH ;Função 4Ch INT 21h ;Interrupção 21h TEST_WRITE_DECIMAL ENDP ;Finaliza o procedimento
PUBLIC WRITE_DECIMAL ;.................................................................; ;Este procedimento escreve um número de 16 bit como um número ; ;sem sinal em notação decimal ; ;Use: WRITE_HEX_DIGIT ; ;.................................................................;
WRITE_DECIMAL PROC PUSH AX ;Põe na pilha o valor do registrador AX PUSH CX ;Põe na pilha o valor do registrador CX PUSH DX ;Põe na pilha o valor do registrador DX PUSH SI ;Põe na pilha o valor do registrador SI MOV AX,DX ;move o valor do registrador DX para AX MOV SI,10 ;move o valor 10 para o registrador SI XOR CX,CX ;zera o registrador CX NON_ZERO: XOR DX,DX ;zera o registrador CX DIV SI ;divisão entre SI PUSH DX ;Põe na pilha o valor do registrador DX INC CX ;incrementa CX OR AX,AX ;não zero JNE NON_ZERO ;salta para NON_ZERO WRITE_DIGIT_LOOP: POP DX ;Retorna o valor em modo reverso CALL WRITE_HEX_DIGIT ;Chama o procedimento LOOP WRITE_DIGIT_LOOP ;loop END_DECIMAL: POP SI ;retira da pilha o valor do registrador SI POP DX ;retira da pilha o valor do registrador DX POP CX ;retira da pilha o valor do registrador CX POP AX ;retira da pilha o valor do registrador AX RET ;Retorna o controle ao procedimento que chamou WRITE_DECIMAL ENDP ;Finaliza o procedimento
PUBLIC WRITE_HEX_DIGIT ;......................................................................; ; ; ;Este procedimento converte os 4 bits mais baixos do registrador DL ; ;num n�mero hexadecimal e os imprime ; ;Use: WRITE_CHAR ; ;......................................................................;
WRITE_HEX_DIGIT PROC PUSH DX ;Põe na pilha o valor do registrador DX CMP DL,10 ;Compara o valor 10 com o valor do registrador DL JAE HEX_LETTER ;se n�o, salta para HEX_LETER ADD DL,"0" ;se , converte em d�gito numrico JMP Short WRITE_DIGIT ;escreve o caracter HEX_LETTER: ADD DL,"A"-10 ;converte um caracter para um n�mero hexadecimal WRITE_DIGIT: CALL WRITE_CHAR ;mostra o caracter na tela POP DX ;Retorna o valor inicial para o registrador DL RET ;Retorna o controle ao procedimento que chamou WRITE_HEX_DIGIT ENDP
PUBLIC WRITE_CHAR ;......................................................................; ;Este procedimento imprime um caracter na tela usando uma fun�o D.O.S.; ;......................................................................;
WRITE_CHAR PROC PUSH AX ;Põe na pilha o valor do registrador AX MOV AH,2h ;Função 2h INT 21h ;Interrupção 21h POP AX ;Retira da pilha o valor inicial do registrador AX RET ;Retorna o controle ao procedimento que chamou WRITE_CHAR ENDP
END TEST_WRITE_DECIMAL ;finaliza o programa
Este programa mostra na tela os números 12345
Quinto exemplo
;nome do programa: five.asm .model small .stack .code
PRINT_ASCII PROC MOV DL,00h ;move o valor 00h para o registrador DL MOV CX,255 ;move o valor decimal 255 para o registrador CX ;usado para fazer um laço com 255 intera�es PRINT_LOOP: CALL WRITE_CHAR ;Chama o procedimento que imprime INC DL ;Incrementa o valor do registrador DL LOOP PRINT_LOOP ;Loop para imprimir 10 caracteres MOV AH,4Ch ;Função 4Ch INT 21h ;Interrupção 21h PRINT_ASCII ENDP ;Finaliza o procedimento
WRITE_CHAR PROC MOV AH,2h ;Função 2h para imprimir um caracter INT 21h ;Imprime o caracter que está em DL RET ;Retorna o controle ao procediemento que chamou WRITE_CHAR ENDP ;Finaliza o procedimento
END PRINT_ASCII ;Finaliza o programa
Este programa mostra na tela o valor dos 256 caracteres do código ASCII.
*****************************************************************************