 |
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:
- ah=0eh
seleciona drive cujo código é passado em dl (0=A:, 1=B:, 2=C:, etc)
- ah=3dh abre um arquivo, cujo nome é uma cadeia terminada por 0 passado
o endereço da cadeia em dx; devolve em ax um handle para o arquivo
(o nome do arquivo deve estar no formato DOS: 8 caracteres + extensão; exemplo:
nomearq: db 'meuteste1.txt', 0)
- ah=3fh lê cx bytes do arquivo cujo handle é passado em bx,
numa área de dados cujo endereço é passado em dx
- Obs: V. pode descobrir o tamanho do arquivo através da função Seek File ah=42h,
al=2 (seek a partir do fim) e cx=dx=0 (cx:dx=offset); ela retorna no par dx:ax
o tamanho do arquivo em bytes (a função tem o mesmo significado da função lseek() em C)
- Em caso de erro as funções acima ligam o CY e o desligam caso contrário.
Veja uma descrição das
funções do DOS para manipular arquivos
(Obs: não use o mau exemplo que aparece lá!)
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.