MC 404AD  -    2º Semestre 2005
Exercícios de programação do 8086
(entrega opcional)

Prof. Célio Guimarães
Atualizado em: 21/09/2005  
Entregas para 22 Set adiadas para 13 Out
As atividades práticas serão feitas por grupos com dois alunos definidos no início do curso ( veja aqui os grupos da turma 404a e da turma 404d) e deverão ser demonstradas no laboratório por um dos membros do grupo, sorteado aleatoriamente. Deverão estar sempre acompanhadas de uma impressão em landscape do programa fonte montado (é o arquivo .lst gerado pelo montador), onde deverá constar no cabeçalho o número do grupo e os nomes dos participantes.
A documentação do programa (via comentários) e uma boa apresentação são imprescindíveis.

Exercício 1.1 Inversão do conteúdo de um vetor.  Entrega: 1 Set

Modifique o exemplo first.asm de forma a inverter o conteúdo de um vetor qualquer de caracteres ASCII, sem usar um vetor auxiliar (use uma convenção adequada para término do vetor, por exemplo, o caracter 0dh, ou 00h usado na linguagem C). Exiba no vídeo o conteúdo do vetor antes e após a inversão. No exemplo dado o vetor conteria após a inversão: "ZYXV...DCBA"

Exercício 1.2: Verificação de entrada de caracteres pelo teclado.   Entrega: 1 Set

Modifique o exemplo 2nd.asm de forma a emitir as seguintes mensagens, dependendo do caracter digitado (que V. deve mostrar no vídeo ao ser digitado e no final da mensagem, como a seguir):
Voce digitou um dígito decimal: 9
Voce digitou uma letra maiúscula: W
Voce digitou uma letra minúscula: x
Voce digitou um caracter de controle:(*)
Voce digitou um caracter que não é letra, dígito ou caracter de controle: <

Obs: consulte aqui a tabela de caracteres ISO Latin-1, também conhecida por ISO-8859-1 (ela é um "super set" do conjunto ASCII, que inclui os caracteres acentuados da maioria das línguas européias, Português inclusive).
(*)Caracteres de controle têm código < 20h e podem ser emitidos pelo teclado digitando Ctl-Letra, onde Ctl-A gera 01h, CTl-B 02h, CTl_C 03h, Ctl-D 04h, ... etc.

Exercício 1.3: Exibir a cadeia de parâmetros passados ao executar um programa .COM   Entrega: 1 Set

Leia a seção intitulada "The Structure of a .COM File" do tutorial do Howard e faça um programa que insere no final da cadeia de parametros os caracteres 0ah e '$' e mostra no vídeo a cadeia através da função de saida de cadeia do DOS: mov ah 09, int 21h.
Obs: No campo "Parameters" da janela "Assemble" do nasmide V. deve inserir uma cadeia de caracteres qualquer, como por exemplo: "Minha terra tem palmeiras onde canta o sabia', as aves que aqui gorjeiam nao gorjeiam como la!". Outra possibilidade é invocar diretamente o programa numa janela DOS como abaixo:
meu_teste Minha terra tem palmeiras onde canta o sabia', as aves que aqui gorjeiam nao gorjeiam como la

 

Exercício 1.4: Contando bits 1 na palavra de estado ( prazo de entrega: 1 Set)

Conforme vimos em aula a palavra de estado não pode ser acessada diretamente mas apenas através das instruções pushf e popf. Faça uma rotina ctbits1 que conta o número de bits 1 na palavra de estado, devolvendo esse número em dx. Chame a rotina após uma operação de multiplicação, (que liga de forma arbitrária bits na palavra de estado) por exemplo:
   mov al, 0ffh
   mov bl, 0ffh
   mul bl
   call ctbits1
   . . .
Depure a sua rotina usando a execução "passo a passo" do debug ou do turbodebugger.


Exercício 1.5: Obtendo os parâmetros de uma rotina com número variável de parâmetros (prazo de entrega: 13 Out)

Escreva uma rotina, mysub, que sem usar instruções pop lê diretamente da pilha os parâmetros passados na sua chamada, onde o último parâmetro contém o número de parâmetros passados. Por exemplo, suponha 3 parâmetros passados assim:
push ax
push bx
pusx cx
mov dx,3
push dx
call mysub
....
Obs: Antes de retornar, mysub deve retirar os parâmetros da pilha.

Exercício 1.6: Busca de cadeia de caracteres (prazo de entrega: 13 Out)

Faça uma rotina que busca (sucessivamente) uma cadeia apontada por si e com comprimento em cx dentro de uma outra cadeia apontada por bx e terminando no endereço apontado por dx; a cada busca com sucesso incremente um contador na memória apontado por di. Por exemplo, a cadeia 'aca' seria encontrada dentro da cadeia 'acacacaca' 4 vezes. Exiba no vídeo as duas cadeias e o número de vezes encontrado. (Este exercício é interessante por requerer um laço dentro de outro).

Exercício 1.7: lendo um arquivo do disco ou disquete. Prazo de entrega: 13 Out

Utilize as seguintes funções do DOS (int 21h, ah= cod-da-função) para ler um arquivo texto do diretório corrente no disco rígido ou de um disquete e exibir o seu conteúdo no vídeo:

1.7.1: escrevendo um carregador de programas .com

Modifique ligeiramente o programa acima para ler um arquivo executável .com a partir do endereço de memória 100h e executá-lo saltando para 100h. Como o seu carregador é também um programa .com, ele deverá ficar na parte alta do segmento de 64K, por exemplo, saltando para um rótulo inicio e reservando uma área grande de memória (digamos, 64000 bytes) antes do rótulo início. V. pode verificar facilmente se o programa a ser carregado não irá invadir a memória onde está carregador (veja observação acima). Teste o seu carregador com um programa simples, como first.com.

Exercício 1.8 (opcional): Exibindo o conteúdo da tabela FAT de um disquete. Prazo de entrega: 13 Out

Modifique o programa desenvolvido na atividade 2 para ler setores de um disquete usando a função do BIOS int 13h ah=02. V. deve simular então os comandos -L e -d do debug assim:
 -L n    - lê o setor n do disquete
 -d      - mostra em hexadecimal o ultimo setor lido em 4 blocos de 128 bytes
           (de forma equivalente a 4 comandos -d consecutivos)

Exercício 1.9: Trabalhando com um segmento de dados apontado por ES. Prazo de entrega: 13 Out

1.9.1 Escreva um programa que copia uma cadeia de caracteres da sua área de dados para um segmento de dados apontado por ES e localizado 64KB (2**16 bytes) acima do segmento onde se encontra o programa. Em seguida V. deve incrementar cada caracter da cadeia localizada no segmento apontado por ES e transferi-la de volta para uma área de dados do seu programa. V. deverá usar a instrução de movimentação de dados do 8086   rep movsb (veja descrição no tutorial do Howard). Exiba a cadeia no vídeo antes e após a transferência através da função int 21h ah=09.

1.9.2 Escreva um programa que preenche a memória de vídeo do PC com um caracter qualquer com letras (foreground) mostradas na cor, digamos, amarela e fundo (background), digamos, na cor azul claro. A memória de vídeo do PC começa no endereço B800:0000h e possui 2048 palavras (para representar 2000 caracteres), onde o byte mais significativo contém o atributo do caracter (cor de frente e de fundo, veja nesta tabela) e o byte menos significativo contém o valor ASCII do caracter. Antes de escrever na memória de vídeo V. deve inicializá-lo com a função do BIOS ah=0, al=3, int 10h que define o video no modo texto com 25 linhas de 80 caracteres cada.
Atenção: não utilize outras funções do BIOS: utilize a instrução rep movsw com um buffer devidamente inicializado na sua área de dados.

Exercicio 1.10: funções de vídeo do BIOS. Prazo de entrega: 13 Out

O programa eat3.asm que exemplifica o uso de funções de vídeo do BIOS, peca por usar a função ah=09, int 21h do DOS, para escrita no vídeo, quando deveria usar a função do BIOS ah=13h, int 10h. Modifique-o com esta finalidade; aproveite e mude também a cor da letra e do fundo das mensagens.

Exercicio 1.11: utilização do macro-montador para gerar fatoriais. Prazo de entrega: 27 Out

Utilizando os recursos do macro-montador do nasm, escreva um programa que gera um vetor de palavras de 32 bits ( no formato dd xyzw ) contendo os valores de n! onde n! <= 2**32. Exiba uma mensagem no vídeo com o número de valores gerados.

Exercicio 1.12: Encadeando interrupções

Escreva um programa que instala uma rotina de interrupção no vetor 0 (divisão por zero), a qual no final da sua execução faz um salto longo para a rotina original do sistema conforme mostra o exemplo a seguir:
myint:	  ; aqui começa minha rotina de interrupção 
  . . .
  . . .
          ; estou finalizando a minha rotina de interrupção:
  jmp far [saveint]  ; em saveint salvei previamente  o ip e cs da rotina do sistema
  ;iret  nunca volta aqui

Exercicio 1.13: Mais um exercício de macros

Escreva uma macro que toma como parâmetro uma constante de 8 bits e que gera em tempo de montagem dois valores correspondendo à representação ASCII-hexadecimal dos 4 bits mais significativos e 4 bits menos significativos da constante, respectivamente. Utilize sua macro no programa myint.asm para exibir corretamente o valor ascii-hexadecimal do número do vetor de interrupção (INTNO).

Exercicio 1.14: Controlando o buffer circular do teclado

A função do DOS mov ah,0ch int 21h, elimina do buffer do teclado todos os caracteres digitados mas ainda não lidos pela aplicação. Ela é util para limpar o buffer após uma tecla ser pressionada e demorar de ser liberada, fazendo com que o microcontrolador do teclado envie repetidamente o mesmo caracter (eventualmente enchendo o buffer do teclado). Implemente a mesma funcionalidade da função do DOS usando exclusivamente as funções de teclado do BIOS.
Extensão 1.14.2: usando exclusivamente as funções de teclado do BIOS descubra o tamanho do buffer do teclado.