Você está na página 1de 10

ESCOLA SUPERIOR DE TECNOLOGIA

INSTITUTO POLITÉCNICO DE CASTELO BRANCO


ENGENHARIA INFORMÁTICA

MICROPROCESSADORES E MICROCONTROLADOES
2º SEMESTRE - 2009/10

FOLHA DE EXERCÍCIOS 1 – MICROPROCESSADOR I8086

1. Utilize o ambiente integrado do MASM 6.13 para executar os seguintes programas:

1.1 1.2

.model small .model Small


.stack .stack
.data .data
var1 db 10 .code
.code .startup
.startup espera:
mov al,'M' mov ah,1 ; consulta se há código disponível
mov ah,14 int 16h
int 10h jz espera ; repetir consulta se não há código
mov al,'i' mov ah,0 ; existe código disponível
mov ah,14 int 16h ; colocar código em AX
int 10h mov ah,14
mov al,'c' int 10h
mov ah,14 cmp al,'f'
int 10h je fim ;se o caracter inserido for 'f' então fim
mov al,'r' cmp al,'F'
mov ah,14 je fim
int 10h jmp espera
mov al,'o' fim:
mov ah,14 .exit
int 10h end
.exit
end

1
2. Escreva um programa que efectue a adição dos registos AL e BL. O resultado da operação
deve ser armazenado no registo CL. Realize a soma com diferentes valores de modo a testar
situações de overfflow etc.

3. Escreva um programa que efectue a subtracção de dois números de 16 bits armazenados em


NUM1 e NUM2. O resultado da operação deve ser armazenado em RESULT.

4. Escreva um programa que efectue a seguinte operação DL = AL + BL - CL.

5. Escreva um programa que efectue a multiplicação de dois números de 16 bits armazenados em


NUM1 e NUM2. O resultado da operação deve ser armazenado em RESULT.

6. Escreva um programa que efectue a divisão de dois números de 8 bits armazenados em BL e


BH. O quociente deve ser armazenado em CL e o resto em CH.

7. Escreva um programa que armazene no registo CX o menor dos dois valores contidos nos
registos AX e BX.

8. Escreva um programa que armazene em DL o maior de três números contidos em AH, BH e


CH.

9. Escreva um programa que, utilizando somas, multiplique dois números armazenados em


NUM1 e NUM2, guardando o resultado em RESULT.

10. Escreva um programa que implemente a seguinte expressão:


IF (( AL < BL ) AND ( AH > BH )) THEN
FIM
ELSE
AL = AL -1
AH = AH +1

11. Escreva um programa que incremente a variável VAR1 uma unidade até esta atingir o valor
10. VAR1 possui inicialmente o valor 0

12. Escreva um programa que determine o comprimento de uma string terminada pelo caracter
nulo. O endereço inicial da string é STRING e o resultado deve ser armazenado no registo DX.

2
13. Escreva um programa que ordene por ordem crescente um array de 5 elementos do tipo byte.

14. Escreva um programa que determine o valor máximo de uma tabela de 10 inteiros sem sinal.
O endereço inicial é TABELA e o valor máximo deve ser guardado no registo DX.

15. Escreva um programa que troque todos os bits dos elementos de um array de 5 elementos do
tipo byte.

16. Escreva um programa que utilizando instruções de shift multiplique o registo AX por 4. Altere
o programa de modo a que o registo AX seja dividido por 2.

17. Escreva um programa que, dado um conjunto de 5 bytes armazenados na memória a partir do
endereço BLOCO, altere os bits desses elementos da seguinte forma:
a) b7,b6,b5,b4,b3,b2,b1,b0  0,0,b5, b4 ,1,1,b1, b0
b) b7,b6,b5,b4,b3,b2,b1,b0  b0,b1,b2,b3,b4,b5,b6,b7

18. Escreva um programa que permita escrever no monitor do computador a mensagem "Olá
mundo". O endereço da string deverá estar contido no registo SI.
Altere o programa de modo a que seja possível escolher a cor dos caracteres da string e a cor de
fundo da string.

19. Escreva um programa que, utilizando um ciclo, permita escrever no écran os números de 1 a
5.

20. Altere o programa anterior de modo a que a string seja escrita nas coordenadas x,y do écran
(as coordenadas devem estar contidas nos registos DL e DH).

21. Escreva um programa que permita ler uma string a partir do teclado do computador,
armazenando-a a partir de uma posição de memória cujo endereço deverá estar contido no registo
SI. O tamanho máximo da string deverá ser de 100 caracteres.

22. Escreva um programa que converta uma string num inteiro. O endereço da string deve ser
colocado no registo SI e o inteiro resultante da conversão armazenado no registo AX. O seu

3
programa deverá detectar as situações de erro que considerar importantes, não convertendo a
string sempre que se verificar uma dessas situações.

23. Escreva um programa que converta um inteiro numa string. O endereço da string deve ser
colocado no registo SI e o inteiro a converter no registo AX. O seu programa deverá detectar as
situações de erro que considerar importantes, não convertendo o inteiro sempre que se verificar
uma dessas situações.

24. Escreva um programa que leia 8 inteiros (>0) a partir do teclado e os guarde num array. O
programa deverá em seguida imprimir no ecrã unicamente os números pares.

25. Escreva um programa que escreva no écran o dobro de um número inserido através do
teclado.

26. Escreva um programa que permita ler através do teclado um número de 4 dígitos e apresente
como resultado a sua decomposição.
Exemplo para o número 2578: 2 milhares 5 centenas 7 dezenas 8 unidades.

27. Escreva um procedimento que permita escrever no monitor do computador uma string.
a) Utilize a passagem de parâmetros por registos.
b ) Utilize a passagem de parâmetros por stack.

28. Escreva um procedimento que permita ler uma string a partir do teclado do computador,
armazenando-a num buffer. O tamanho máximo da string deverá ser de 100 caracteres.
a) Utilize a passagem de parâmetros e retorno de valores por registos.
b ) Utilize a passagem de parâmetros e retorno de valores por stack.

29. Escreva um procedimento que converta uma string num inteiro. O seu procedimento deverá
detectar as situações de erro que considerar importantes, não convertendo a string sempre que se
verificar uma dessas situações.
a) Utilize a passagem de parâmetros e retorno de valores por registos.
b ) Utilize a passagem de parâmetros e retorno de valores por stack.

30. Escreva um procedimento que converta um inteiro numa string.


a) Utilize a passagem de parâmetros por registos.
b ) Utilize a passagem de parâmetros por stack.

4
31. Escreva um programa que permita ler uma string a partir do teclado e que quando terminar a
inserção da string permita escrever no ecrã o número total de caracteres contidos na string.

32. Escreva um programa que, fazendo uso dos procedimentos anteriores, permita ler um valor inteiro
a partir do teclado e escreva no ecrã o seu quadrado.

33. Com certeza conhece a função strcpy da biblioteca de funções da linguagem de programação C.
Desenvolva então um programa em assembly que copia uma string posicionada no endereço SOURCE
para uma string posicionada no endereço DEST. Ambas as strings terminam com o caracter zero.

34. Escreva um programa em assembly que, tal como a função strcmp da linguagem C, compara duas
strings posicionadas nos endereços STR1 e STR2, respectivamente. O resultado da comparação será
armazenado no acumulador, tendo em atenção os seguintes critérios:
AX > 0 se STR1 > STR2
AX = 0 se STR1 = STR2
AX < 0 se STR1 < STR2

35. Escreva um programa que executa a concatenação de duas strings STR1 e STR2 (função strcat da
linguagem C), devendo o resultado da concatenação ficar guardado em STR1.

36. Escreva um programa que, fazendo acesso directo à memória vídeo, escreva uma string numa
posição (x, y) e determinado atributo. A memória vídeo começa no endereço 0B800:0000 e é disposta
como se fosse um array sequencial, alternando caracter com atributo, isto é, num byte está o caracter e
no seguinte o atributo desse caracter.

37. Elabore um programa que, fazendo uso dos procedimentos anteriores, implemente uma
calculadora de números inteiros. A calculadora deverá começar por pedir o primeiro operando,
depois a operação (+,-,*,/, %) e finalmente o segundo operando. No final deverá apresentar o
resultado da operação. O programa deverá efectuar todo o controlo de erros necessário ao seu
bom funcionamento.

38. Escreva um procedimento que, fazendo acesso directo à memória vídeo, escreva uma
string numa posição (x, y) e determinado atributo. A memória vídeo começa no endereço
0B800:0000 e é disposta como se fosse um array sequencial, alternando caracter com atributo,
isto é, num byte está o caracter e no seguinte o atributo desse caracter.

39. Desenvolver um programa que toque uma melodia no computador.


Este programa deverá utilizar o altifalante do PC para reproduzir a melodia pretendida. A utilização do
altifalante passa por programar o canal 2 do circuito temporizador do PC, de modo a este emitir uma
onda quadrada, que simula uma onda sinusoidal, correspondente à frequência que se deseja reproduzir.

5
Será necessário também ligar e desligar o altifalante.
Para concluir este programa deverá primeiro desenvolver alguns procedimentos que tornarão a
programação mais simples. Esses procedimentos são os seguintes:
- programar o circuito temporizador do computador
- ligar o altifalante
- desligar o altifalante
- tocar uma frequência no altifalante
- esperar um determinado tempo

Programação do circuito temporizador


A programação do canal 2 do circuito temporizador envolve a utilização do porto 43h. A informação
deste porto é a seguinte:

Porto 43h
bit 7 bit 0

tipo de contagem
Seleccionar contador 0 - contagem em binário
00 - contador 0 1-contagem em BCD
modo de contagem
01 - contador 1 000 - interrupção no fim da contagem
10 - contador 2 001 - modo monoflop
11 - não utilizada 010 - gerador de impulsos
011 - gerador de onda quadrada
100 - pulso gerado por software
modo de leitura/escrita do contador 101 - pulso gerado por hardware
00 - counter latch instrucion
01 - apenas o byte menos significativo
10 - apenas o byte mais significativo
11 - byte menos sig. depois byte mais sig.

Para o altifalante funcionar como pretendido deve-se utilizar a contagem em binário, geração de onda
quadrada, utilização de 2 bytes e utilização do contador 2.

Ligar e desligar o altifalante


O altifalante é ligado e desligado através do bit 1 do porto 61h. O bit 0 do mesmo porto liga e desliga o
contador 2 do circuito temporizador. Para ligar o altifalante e o contador 2 colocar estes 2 bits a um e
para desligar colocar estes 2 bits a 0. Os restantes bits não devem ser alterados.

Tocar uma frequência no altifalante


Depois de programado o circuito temporizador e ligado o altifalante, conforme feito nos passos
anteriores, é simples tocar uma frequência no altifalante. Para isso basta programar o contador 2 de
modo a este gerar a onda quadrada com a frequência pretendida.
Este porto é de 8 bits mas pode receber valores de 16 bits. Para isso devem ser enviados os 8 bits
menos significativos primeiro e o 8 bits mais significativos depois (ver código exemplo mais à frente).
A frequência máxima do temporizador é 1193180 Hz. O valor que se coloca no porto 42h é o valor
pelo qual se deve dividir esta frequência de modo a obter a frequência pretendida.
Exemplo: para produzir uma frequência de 440 Hz deve-se colocar no porto o valor 1193180 / 440 =
2712. O código seguinte mostra como se deve escrever este valor no porto 42h.

mov ax,2712
out 42h,al ; enviar os 8 bits menos significativos para o porto 42h
mov al, ah
out 42h,al ; enviar os 8 bits mais significativos para o porto 42h

O procedimento a desenvolver deverá ter como parâmetros de entrada o valor a colocar neste porto.

O esquema seguinte mostra como os vários portos se interligam de modo a produzir um som no
altifalante.

6
Porto 61h
bit 0

circuito
temporizador
contador
0
Amplif. filtro.
contador
1
contador
2
porto 42h
gate

Esperar um determinado tempo


Para esperar um determinado tempo pode-se utilizar o valor do relógio apresentado no endereço
0000:046Ch. O valor desta posição de memória é incrementado aproximadamente 18 vezes por
segundo. Assim para esperar um ciclo de relógio basta que se espere que este valor seja incrementado
de 18 vezes.
O procedimento deverá ter como parâmetros de entrada o nº de incrementos que deve esperar.

Tocar uma melodia


Para tocar uma melodia serão necessários os seguintes passos:
- programar o circuito temporizador
- ligar o altifalante
- repetir
- ver código da frequência a tocar
- colocar esse valor no porto 42h
- esperar o tempo de duração da nota
- passar à frequência seguinte
- até que se chegue à última frequência
- desligar o altifalante

Definir uma melodia


Para tocar a melodia devem ser dadas as informações sobre:
- número de notas da melodia
- nota a tocar (no formato próprio para enviar para o porto 42h)
- tempo que se deve tocar a nota (já em número de incrementos)
Ao se declarar uma melodia pode-se por então:
número de notas, nota 1, tempo nota 1, nota 2, tempo nota 2, ...
O exemplo seguinte representa uma melodia com 7 notas:
Musica dw 7,4561,1,4062,10,3620,1,3417,10,3044,1,2712,1,2416,2

40. Desenvolver um programa que implemente um pequeno teclado electrónico.


Utilizando os procedimentos implementados no programa anterior fazer um pequeno teclado
electrónico. Como teclas devem ser utilizadas as teclas de ‘1’ a ‘7’ (1=dó, 2=ré, etc). Cada nota deve
ser tocada durante um ciclo de tempo (tempo de espera de 1).
Os valores, em Hz, das notas são as seguintes (das oitavas 4 a 7):

Nota oitava 4 oitava 5 oitava 6 oitava 7


Dó 130.1 261.6 523.3 1046.5
Ré 146.8 293.7 587.3 1174.7
Mi 164.8 329.6 659.3 1328.5
Fá 174.6 349.2 698.5 1396.9
Sol 196.0 392.0 784.0 1568.0
Lá 220.0 440.0 880.0 1760.0
Si 247.0 493.0 987.8 1975.5

7
A oitava a utilizar no programa pode ser qualquer uma das presentes na tabela
Sugere-se a criação de uma tabela que contenha as notas já convertidas para o formato exigido pelo
procedimento tocar as frequências.
A tabela seguinte mostra esses valores para a oitava 5:
oitava_5 dw 4561,4062,3620,3417,3044,2712,2416

41. Pretende-se que escreva uma Rotina de Atendimento à Interrupção (RAI) 60h. Esta rotina
deve aceitar como parâmetros de entrada CX e SI representando respectivamente o número de
elementos de um array de bytes e um apontador para este, e deve ter como resultado em AX a
soma de todos os elementos do array.
Este trabalho deve englobar as seguintes tarefas:
 Procedimento para executar as tarefas pedidas e de acordo com as regras de uma RAI;
 Procedimento para ler a tabela de vectores de interrupção;
 Procedimento para escrever na a tabela de vectores de interrupção;
 Programa principal (startup) onde deve chamar os procedimentos para ler e escrever na
tabela de vectores de interrupção de forma a guardar o vector de interrupção “antigo” (que
deve ser reposto no final do programa), colocar o vector de interrupção novo e chamar a
interrupção 60h de modo a testar a RAI;

42. Pretende-se que escreva uma Rotina de Atendimento à Interrupção (RAI) 61h. Esta rotina
deve aceitar como parâmetro de entrada SI representando um apontador para uma string, e
deve ter como resultado, em AX, o número de caracteres da string.
Este trabalho deve englobar as seguintes tarefas:
 Procedimento para executar as tarefas pedidas e de acordo com as regras de uma RAI;
 Procedimento para ler a tabela de vectores de interrupção;
 Procedimento para escrever na a tabela de vectores de interrupção;
 Programa principal (startup) onde deve chamar os procedimentos para ler e escrever na
tabela de vectores de interrupção de forma a guardar o vector de interrupção “antigo” (que
deve ser reposto no final do programa), colocar o vector de interrupção novo e chamar a
interrupção 61h de modo a testar a RAI;

8
A tabela de vectores de interrupção está representada na figura.

43. Escrever uma rotina de atendimento para a interrupção 1Ch.


A interrupção 1Ch é originada 18 vezes por segundo. A rotina deve colocar no canto superior direito
do ecrã o valor dos minutos e segundos passados desde que o programa foi activado. O programa só
deverá activar a rotina desenvolvida e esperar pelo pressionar de uma tecla, após o que deve
desinstalar a rotina.
Para fazer este programa deverão ser desenvolvidos os seguintes procedimentos:
- procedimento para ler a tabela de vectores de interrupção e retornar o vector para uma dada
interrupção.
- procedimento para escrever na tabela de vectores de interrupção o novo vector de uma dada
interrupção.
- rotina de atendimento a interrupção 1Ch

Procedimento para ler a tabela de vectores de interrupção


A tabela de vectores de interrupção começa no endereço 0000:0000. Os vectores das diversas
interrupções estão ordenados por ordem crescente e cada um possui 4 bytes (2 para o offset da rotina e
2 para o segmento, respectivamente). Assim, para saber qual o endereço da interrupção pretendida
basta multiplicar o seu código por 4.
Parâmetros de entrada
AX = código da interrupção
Parâmetros de saída
CX = offset da rotina de atendimento
DX = segmento da rotina de atendimento

Procedimento para escrever na tabela de vectores de interrupção


Seguir o mesmo raciocínio do procedimento anterior
Parâmetros de entrada

9
AX = código da interrupção
CX = offset da nova rotina de atendimento
DX = segmento da nova rotina de atendimento

Rotina de atendimento a uma interrupção


As rotinas de atendimento a uma interrupção devem ser sempre pensadas com cuidado. Estas rotinas
devem obedecer às seguintes regras:
- terminar sempre com um IRET
- NUNCA alterar qualquer registo (salvaguardar os registos necessários no princípio da rotina
e recuperá-los no fim)
- NÃO utilizar variáveis declaradas no segmento de dados, mas sim no segmento de código.

Para desenvolver a rotina em questão seguir os seguintes passos:


- Escrever no ecrã na posição (70,1) o caracter ‘0’
- De cada vez que for chamada incrementar o valor imprimido (na gama 0-9)
- incrementar o valor apenas uma vez por segundo
- apresentar o valor do tempo em segundos (2 digitos apenas)
- apresentar o valor do tempo em minutos (mm:ss)
- apresentar o valor em horas (hh:mm:ss)

44. Escrever um programa que toque uma melodia em background.


O programa a desenvolver deverá associar a cada tecla numérica uma melodia. Essa melodia deverá
ser tocada enquanto o programa espera por outra tecla, ou seja, deverá ser tocada em background.
Este programa deverá utilizar todos os procedimentos utilizados nesta folha de exercícios. Deverá
ainda utilizar uma rotina de atendimento à interrupção 1Ch para permitir tocar a melodia em
background. Para simplificar esta rotina cada nota da melodia deverá demorar um ciclo de tempo.

10

Você também pode gostar