Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 1
Instituto Federal de Educação, Ciência e Tecnologia de São Paulo
Apostila de Laboratório de Microprocessadores
Prof. Dr. Gilberto Igarashi
2016
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 2
Experiência 1: Apresentação da estrutura da disciplina, editores,
compiladores e simuladores
Objetivo
Apresentar para os alunos a estrutura da disciplina, bem como as ferramentas que serão utilizadas durante a disciplina.
Conteúdo
Esta disciplina tem como objetivo introduzir o aluno na programação de software embarcado (firmware) bem como
apresentar os dispositivos que irão executa-lo: os microprocessadores e os microcontroladores.
- os Microprocessadores são dispositivos digitais que possuem basicamente a CPU (Central Processing Unit – Unidade
de Processamento Central), onde esta localizada a ALU (Aritmetic Logic Unit – Unidade Lógica Aritmética)
responsável pela execução dos cálculos, e o circuito controlador para acesso a memória.
- os Microcontroladores são dispositivos digitais que possuem um microprocessador interno otimizado além de
periféricos externos adicionais responsáveis por diversas funções de controle/automação. Ex: interface I/O, timers,
interface serial, conversores analógico/digitais.
Atualmente, as ferramentas para a programação destes dispositivos evoluíram de forma que a sua programação pode ser
realizada em diversas linguagens. Estas podem ser classificadas, basicamente, em:
- linguagem de baixo nível: linguagem de programação mais próximo ao nível da máquina, que permite a melhor
compreensão e domínio do hardware utilizado, bem como o menor código possível; em contrapartida torna o código
não portável entre microcontroladores/microprocessadores de diferentes modelos/fabricantes. Ex: linguagem Assembly
- linguagem de alto nível: linguagem de programação mais próximo ao nível do usuário, oferecendo mais facilidade na
abstração para a elaboração do código e na portabilidade de código entre microcontroladores/microprocessadores de
diferentes modelos/fabricantes; em contrapartida o código geralmente acaba ficando com tamanho superior a um código
de mesma função elaborado diretamente na linguagem Assembly. Ex: linguagem C, linguagem Basic.
Um programa escrito em linguagem Assembly ou em linguagem C (chamado de PROGRAMA FONTE), não pode ser
diretamente processado pelo microprocessador/microcontrolador do sistema, devendo primeiramente ser traduzido para
a sua linguagem de máquina, com o uso de tabelas ou através de um programa destinado para tal tarefa chamado de
COMPILADOR.
Define-se COMPILADOR como um programa aplicativo que transforma um arquivo constituído por códigos ASCII,
gerado normalmente por um editor de textos, em um arquivo binário que contém os bytes correspondentes às instruções
(códigos de máquina) do microprocessador/microcontrolador. Como resultado da compilação geralmente são criados
dois arquivos:
- arquivo de mesmo nome, porém, com a extensão “.LST”, que corresponde a um arquivo texto que mostra o resultado
da compilação, contendo para cada linha de programa, o código de máquina correspondente à instrução, sendo muito
útil na depuração de erros de compilação.
- arquivo de mesmo nome, porém com a extensão “.HEX”, usado por gravadores de memórias e microcontroladores e
também pelo programa simulador.
Existem no mercado programas, chamados IDE (Integrated Development Enviroment – Ambiente de Desenvolvimento
Integrado) que disponibilizam uma interface contendo o editor de texto, o compilador e ferramentas para debug num
mesmo programa. Ex: Reads51, MPLAB IDE, Keil.
Também existem simuladores dos mais diversos capazes de simular tanto o funcionamento do
microprocessador/microcontrolador, quanto hardwares externos conectados a ele. Ex: EdSim51, Proteus.
Em nossas aulas utilizaremos os seguintes programas:
- DosBox (simulador do MS-DOS)
- Debug (simulador para x86)
- EdSim51 (simulador para 8051)
- SDCC (compilador C para 8051)
- Keil C51 (IDE para 8051)
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 3
Experiência 2: Introdução ao Debug, sistemas microprocessados e
movimentação de variáveis no microprocessador x86
Objetivo
Apresentar o software Debug, noções básicas da estrutura de um microprocessador e as instruções em linguagem
Assembly básicas utilizadas para a movimentação de variáveis.
Conteúdo
Antes de iniciarmos os trabalhos do laboratório serão introduzidos de forma subjetiva alguns conceitos acerca da
estrutura básica que acompanha a maior parte dos sistemas microprocessados, ilustrado pela Figura 1.
Figura 1: Estrutura básica de um sistema microprocessado genérico
Memória: são dispositivos responsáveis por armazenar os dados (entenda-se números binários). Funcionam como um
armário contendo várias gavetas, conforme ilustra a Figura 2. Portanto, quando dissermos “armazene o valor 20H no
endereço de memória 01H” estaremos armazenando o dado 20H na gaveta de endereço 01H.
Figura 2: Diagrama representativo de uma memória genérica
Microprocessador: é o dispositivo central, que comanda todos os outros dispositivos segundo o firmware programado,
conforme ilustra a Figura 3. Possui internamente uma CPU (que contém a ULA, responsável pela execução de
operações aritméticas) e uma memória interna dedicada, cujas gavetas são identificadas por nomes, e não por endereço
de memória. Estas gavetas são chamadas de registradores e cada um destes registradores possui uma função específica.
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 4
Figura 3: Diagrama representativo de um microprocessador genérico
O software Debug tem como objetivo simular a estrutura básica mostrada na Figura 1. Inicializando o Debug, e
digitando o comando “?” obtemos uma lista dos comandos disponíveis.
A (Assemble)
C (Compare)
D (Dump)
E (Enter)
F (Fill)
G (Go)
H (Hexarithmetic)
I (Input)
L (Load)
M (Move)
N (Name)
P (Ptrace)
Q (Quit)
R (Register)
S (Search)
T (Trace)
U (Unassemble)
W (Write)
Comando R (Register)
Mostra e altera o conteúdo dos registros. Digitando:
-R
serão exibidos na tela o conteúdo dos registradores:
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=075F ES=0B3C SS=0B3C CS=075F IP=0100 NV UP EI PL NZ NA PO NC
0B3C:0100 030000 MOV [0000],AX
Todos estes registros tem tamanho de 16 bits. Dentre eles podemos destacar:
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 5
AX,BX,CX,DX ; registradores de dados genéricos
DS ; (Data Segment) registrador que aponta para um endereço de referência na memória de dados
CS ; (Code Segment) registrador que aponta para um endereço de referência na memória de programa
Para alterar o valor de um determinado registro, por exemplo alterar o valor contido no registro AX de 0000H para
12ABH, digitamos:
-R AX
AX 0000
:12AB
Portanto, digitando novamente:
-R
Será exibido:
AX=12AB BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=075F ES=0B3C SS=0B3C CS=075F IP=0100 NV UP EI PL NZ NA PO NC
0B3C:0100 030000 MOV [0000],AX
Comando D (Dump)
Mostra e altera o conteúdo da memória de dados, ou da memória de programa. Para visualizar o valor contido nos
endereços da memória de dados digitamos:
-D DS:0000
Será exibido:
075F:0000 CD 20 5E A7 00 EA FD FF-AD DE 4F 03 A3 01 8A 03 . ^.......0.....
075F:0010 A3 01 17 03 A3 01 92 01-01 01 01 00 02 FF FF FF ................
075F:0020 FF FF FF FF FF FF FF FF-FF FF FF FF 00 00 00 00 ................
075F:0030 00 00 14 00 18 00 5F 07-FF FF FF FF 00 00 00 00 ......_.........
075F:0040 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0050 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0060 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0070 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
Cada endereço de memória tem tamanho de 32 bits e é identificado por um endereço composto de 16 bits + 16 bits, cujo
valor dos 16 bits mais significativos esta gravado no registro DS.
Para visualizar o valor contido nos endereços da memória de programa digitamos:
-D CS:0100
Será exibido:
075F:0100 CD 20 5E A7 00 EA FD FF-AD DE 4F 03 A3 01 8A 03 . ^.......0.....
075F:0110 A3 01 17 03 A3 01 92 01-01 01 01 00 02 FF FF FF ................
075F:0120 FF FF FF FF FF FF FF FF-FF FF FF FF 00 00 00 00 ................
075F:0130 00 00 14 00 18 00 5F 07-FF FF FF FF 00 00 00 00 ......_.........
075F:0140 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0150 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0160 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0170 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
Cada endereço de memória tem tamanho de 32 bits e é identificado por um endereço composto de 16 bits + 16 bits, cujo
valor dos 16 bits mais significativos esta gravado no registro CS.
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 6
Comando E (Enter)
Altera o valor contido em um endereço da memória de dados, ou da memória de programa.
Para alterar o conteúdo do endereço da memória de dados 075F:0000H de CDH para 41H digitamos:
-E DS:0000
Será exibido na tela o endereço de memória e o valor atual contido neste endereço (no caso CDH):
075F:0000 CD.
Para altera-lo basta digitar após o ponto ‘.’ o novo valor (no caso 41H):
075F:0000 CD.41
Se for digitado <Enter> após digitar o novo valor o processo de alteração de valores se encerra. Se for digitado
<Space> será exibido o valor do endereço seguinte e solicitado o seu novo valor.
Portanto, digitando o comando:
- D DS:0000
Será exibido:
075F:0000 41 20 5E A7 00 EA FD FF-AD DE 4F 03 A3 01 8A 03 A ^.......0.....
075F:0010 A3 01 17 03 A3 01 92 01-01 01 01 00 02 FF FF FF ................
075F:0020 FF FF FF FF FF FF FF FF-FF FF FF FF 00 00 00 00 ................
075F:0030 00 00 14 00 18 00 5F 07-FF FF FF FF 00 00 00 00 ......_.........
075F:0040 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0050 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0060 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0070 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
Comando A (Assemble)
Insere uma instrução (código) Assembly na memória de programa.
Vamos utilizar como exemplo nesta etapa uma instrução simples para movimentação de valores contidos nos endereços
de memória: a instrução MOV. Supondo que desejamos movimentar (copiar) o valor contido no registrador AX para o
endereço de memória de dados 075F:0000H. Para isto podemos utilizar a instrução MOV da seguinte forma:
MOV [0],AX
O mecanismo básico de funcionamento de um sistema microprocessado é ilustrado na Figura 4:
Figura 4: Funcionamento básico de um sistema microprocessado para armazenar um valor na memória de dados
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 7
A etapa 1 é chamada de Fetch e consiste na busca da instrução a ser executada na memória de programa (neste caso
MOV [0],AX).
A etapa 2 é a execução da instrução propriamente dita.
Esta instrução é o nosso programa a ser executado pelo microcontrolador, e este programa deve ser armazenado na
memória de programa. Ela está no formato texto e, para que possa ser armazenada na memória de programa, deve ser
convertido para número. O programa responsável por este trabalho é o COMPILADOR, e o Debug já possui um
compilador interno, acessível pelo comando A.
Portanto, para inserir nossa instrução precisamos definir o endereço de memória onde será inserida esta instrução.
Supondo que desejamos inserir esta instrução no endereço de memória de programa 075F:0100H. Para isto, digitamos o
comando A da seguinte forma:
-A CS:0100
Em seguida será exibido a posição de memória de programa 075F:0100H e esperado a digitação da instrução Assembly
para compilação. Digitando nosso código, teremos:
075F:0100 MOV [0],AX 075F:0103
Se tudo foi digitado corretamente até aqui o Debug irá interpretar a instrução Assembly digitada, compila-la e
armazena-la na memória de programa no endereço 075F:0100H.
Para verificar basta fazer uso do comando D:
-D CS:0100
Será exibido:
075F:0100 A3 00 00 A7 00 EA FD FF-AD DE 4F 03 A3 01 8A 03 ..........0.....
075F:0110 A3 01 17 03 A3 01 92 01-01 01 01 00 02 FF FF FF ................
075F:0120 FF FF FF FF FF FF FF FF-FF FF FF FF 00 00 00 00 ................
075F:0130 00 00 14 00 18 00 5F 07-FF FF FF FF 00 00 00 00 ......_.........
075F:0140 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0150 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0160 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0170 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
Comando U (Unassemble)
Mostra na tela um resumo do programa digitado até o momento. Para exibir o código armazenado a partir da posição de
memória de programa CS:0100H digitamos:
-U CS:0100
Será exibido:
075F:0100 A30000 MOV [0000],AX
075F:0103 0000 ADD [BX+SI],AL
075F:0105 0000 ADD [BX+SI],AL
075F:0107 0000 ADD [BX+SI],AL
075F:0103 0000 ADD [BX+SI],AL
075F:0109 0000 ADD [BX+SI],AL
075F:010B 0000 ADD [BX+SI],AL
075F:010D 0000 ADD [BX+SI],AL
075F:010F 0000 ADD [BX+SI],AL
075F:0111 0000 ADD [BX+SI],AL
075F:0113 0000 ADD [BX+SI],AL
075F:0115 0000 ADD [BX+SI],AL
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 8
Comando T (Trace)
Executa, instrução por instrução, o programa armazenado na memória de programa.
Para que o microprocessador saiba onde está localizada na memória de programa a instrução a ser executada ele faz uso
do registrador IP. Se, digitando o comando R obtermos:
AX=12AB BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=075F ES=075F SS=075F CS=075F IP=0100 NV UP EI PL NZ NA PO NC
075F:0100 A30000 MOV [0000],AX
Significa que o processador irá executar a instrução armazenada no endereço 16bits:16bits, onde os 16bits da esquerda
correspondem ao valor armazenado no registro CS e os 16bits da direita correspondem ao valor armazenado no registro
IP. Ou seja, será executada a instrução contida no endereço 075F:0100H.
Nossa próxima etapa é executar a instrução programada. Para isto, basta executar a função T digitando:
-T
Será exibida na tela:
AX=12AB BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=075F ES=075F SS=075F CS=075F IP=0103 NV UP EI PL NZ NA PO NC
075F:0003 A7 CMPSW
Repare que o registro IP incrementou em 3 (quantidade de bytes da instrução “MOV [0],AX” executada). Para
visualizar o valor de AX copiado no endereço de memória de dados 075F:0000H basta utilizar o comando D:
-D DS:0000
Será exibida na tela:
075F:0000 AB 12 00 A7 00 EA FD FF-AD DE 4F 03 A3 01 8A 03 ..........0.....
075F:0010 A3 01 17 03 A3 01 92 01-01 01 01 00 02 FF FF FF ................
075F:0020 FF FF FF FF FF FF FF FF-FF FF FF FF 00 00 00 00 ................
075F:0030 00 00 14 00 18 00 5F 07-FF FF FF FF 00 00 00 00 ......_.........
075F:0040 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0050 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0060 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
075F:0070 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
Repare que foram armazenados nos endereços de memória de dados:
075F:0000 AB
075F:0001 12
Sendo que no registro AX o valor armazenado é 12ABH. Este formato de armazenamento de valores é chamada de
Little-endian. A sequência de armazenamento oposta a esta é chamada de Big-endian, conforme ilustra a Figura 5.
Figura 5: Formatos Big-endian e Little-endian
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 9
Comandos N, W e L
No Debug é possível salvar seu programa em linguagem Assembly em um arquivo para que o mesmo possa ser
recuperado mais tarde. Os arquivos são salvos via Debug com formatação binária e com extensão “.com”. Um resumo
do procedimento a ser seguido é ilustrado a seguir:
-N TESTE.COM
-R
AX=12AB BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=075F ES=075F SS=075F CS=075F IP=0100 NV UP EI PL NZ NA PO NC
075F:0100 A30000 MOV [0000],AX
-R BX
BX 0000
:0000
-R CX
CX 0000
:0500
-R
AX=12AB BX=0000 CX=0500 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=075F ES=075F SS=075F CS=075F IP=0100 NV UP EI PL NZ NA PO NC
075F:0100 A30000 MOV [0000],AX
-W
Gravando 00500 bytes
Para salvar o programa no arquivo “.com” primeiro deve ser atribuído um nome ao mesmo. Isto é conseguido através do
comando N seguido do nome do arquivo com extensão “.com”. Este nome não deve ultrapassar 8 caracteres de
tamanho, nem utilizar caracteres com acento.
O passo seguinte é carregar os registradores BX e CX com o tamanho do programa em bytes que, nos nossos exemplos
de aula, sempre iniciarão a partir do endereço CS:0100H. Uma prática que torna esse processo menos trabalhoso é
sempre colocar um tamanho fixo que seja sempre acima do tamanho real do programa. Um bom valor para as aulas são
500 bytes, uma vez que os nossos programas dificilmente ultrapassarão este limite. Portanto, admitindo a quantidade de
500 bytes será salvo no arquivo “.com” os bytes contidos na memória de programa a partir do endereço CS:0100H até o
endereço CS:0100H+499 = CS:02F3H.
Por último, basta utilizar o comando W que automaticamente salvará os bytes da memória de programa no arquivo
“.com” definido.
Uma vez que o arquivo esta salvo é possível abri-lo novamente. Um resumo do procedimento a ser seguido é ilustrado a
seguir:
-N TESTE.COM
-L
Antes de carregar o arquivo “.com” salvo deve ser informado ao programa Debug o nome deste arquivo através do
comando N. Em seguida, basta utilizar o comando L que carregará os bytes salvos nas mesmas posições que se
encontravam anteriormente.
Exercícios
1) Verifique o que realiza a instrução MOV AX,[0] utilizando os comandos do Debug mostrados até aqui.
2) Quantos bytes são ocupados na memória de programa para armazenar o programa abaixo?
MOV AX,[0000]
MOV [0010],AX
MOV AX,[0002]
3) Utilizando os comandos do Debug carregue os seguintes valores nos formatos Big-endian e Little-endian:
a) valor ABCDEFH a partir do endereço de memória de dados 075F:0000H
b) valor 123456H a partir do endereço de memória de dados 075F:0020H
4) A partir do endereço da memória de dados 075F:0000H preencha 16 posições seguidas com os valores de 00H a 0FH.
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 10
Experiência 3: Registradores e movimentação de variáveis no
microprocessador x86
Objetivo
Apresentar com mais detalhes os registradores do microprocessador x86 e as instruções em linguagem Assembly
básicas utilizadas para a movimentação de variáveis.
Conteúdo
Digitando o comando R no Debug temos na tela uma visão dos principais registros do x86:
AX=12AB BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=075F ES=075F SS=075F CS=075F IP=0100 NV UP EI PL NZ NA PO NC
075F:0100 A30000 MOV [0000],AX
O processador x86 possui 4 registradores de uso geral de 16 bits cada denominados AX, BX, CX e DX, conforme
ilustra a Figura 6. O termo uso geral é exatamente porque o programador pode usá-los para evitar armazenar um
determinado dado na memória externa, economizando assim o tempo de busca na memória de dados e tornando a
execução do programa mais veloz. Além disso, esses registradores podem ser divididos logicamente em 2 sub-
registradores de 8 bits, assim, o lado mais significativo do registrador de 16 bits recebe a letra H (High) e o lado menos
significativo recebe a letra L (Low), formando então um novo conjunto de 8 registradores de 8 bits. É importante notar
que essa divisão é somente lógica pois, fisicamente, o espaço ocupado pelo registrador e seus sub-registradores é o
mesmo. Ou seja, uma alteração em AH alteraria automaticamente o conteúdo de AX.
Figura 6: Registradores de uso geral do x86
Os registradores de uso geral também possuem características de uso específico. O registrador CX é usado pelo
processador para armazenar valores de contagem de loops, o registrador AX é usado para armazenar resultados de
multiplicações e parcelas de divisões, o registrador BX é usado para armazenar endereços base (ponteiro) para acesso
indireto à memória de dados e o registrador DX é usado para armazenar endereços de dispositivos de entrada e saída
para comunicação do processador com o mundo externo.
Outro grupo de registradores são os registradores de ponteiro e de índice, conforme ilustra a Figura 7. Tais registradores
são de uso específico e interno ao processador, ou seja, seus valores referenciam operações internas ao processador e se
alterados influenciarão nas tarefas do mesmo. Como o próprio nome já diz eles têm como função indicar ao processador
o ponto onde se encontra determinada informação.
Figura 7: Registradores de ponteiro e de índice do x86
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 11
O registrador SP indica o ponto onde está localizado o topo da pilha de armazenamento do processador na memória. O
conceito de pilha será detalhado mais adiante. Os registradores BP, SI e DI são aplicados para acessos em programação
de forma mais automatizada. Eles não serão explorados neste curso. Por último o registrador IP, que tem a função de
indicar o endereço de memória em que está situada a próxima instrução do programa que será executada.
Por último existe o grupo de registradores de segmento, conforme ilustra a Figura 8. Tais registradores apontam para os
segmentos da memória onde estão armazenadas as informações necessárias para o funcionamento do processador. O
registrador CS indica o segmento da memória de programa onde se encontra o código do programa que será executado.
O registrador DS indica o segmento da memória de dados onde estão armazenadas as variáveis utilizadas no programa.
O registrador SS indica o segmento da memória de dados onde a pilha do processador está armazenando os dados a ela
destinados. O registrador EX indica o segmento extra, uma área de dados adicional do processador.
Figura 8: Registradores de segmento do x86
O processador x86 possui ainda 8 flags, com tamanho de um bit, usados para armazenar estados do sistema (flags de
status) e controlar as operações internas do mesmo (flags de controle), conforme ilustra a Figura 9.
Figura 9: Flags do processador x86
Os flags de status são modificados pelo processador geralmente após operações aritméticas ou lógicas, de forma a
refletir propriedades dos resultados dessas operações. Os flags de controle são modificados pelo usuário para alterar
alguma característica particular do sistema. Elas serão exploradas com mais detalhes numa próxima etapa desta apostila.
A instrução MOV possui a seguinte sintaxe:
MOV operando1, operando2
Onde operando1 e operando2 são, respectivamente, o destino e a origem. Apesar de intuitivamente lembrar a ideia
de mover, na realidade faz uma cópia no destino do valor armazenado na origem. As possibilidades básicas para
movimentação de dados são:
a) modo constante imediato
Ex: Copiar um valor constante de 16 bits para um registrador de 16 bits
MOV DX,8955 ; armazena o valor 8955H no registrador DX
Ex: Copiar um valor constante de 8 bits para um registrador de 8 bits
MOV AL,54 ; armazena o valor 54H no registrador AL
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 12
b) modo imediato
Ex: Copiar o valor contido em um endereço de memória para o registrador
MOV AL,[0350] ; copia o valor armazenado no endereço de memória de dados
; DS:0350H para o registrador AL
c) modo registrador
Ex: Copiar o valor contido em um registrador para um endereço de memória
MOV [0220],DL ; copia o valor armazenado no registrador DL para o endereço de
; memória de dados DS:0220H
Ex: Copiar o valor contido em um registrador para outro registrador
MOV DX,AX ; copia o valor armazenado no registrador AX no registrador DX
d) modo indireto
Este modo permite o acesso indireto da memória de dados utilizando o registrador BX como apontador.
Ex: Copiar o valor contido no endereço apontado por DS:BX no registrador, admitindo que o conteúdo do registrador
DS seja igual a 075FH.
MOV BX,0010 ; armazena o valor 0010H no registrador BX
MOV DX,[BX] ; copia o valor contido no endereço apontado por DS:BX
;(075F:0010H) no registrador DX
No anexo II da apostila é mostrado o set de instruções completo do microprocessador x86.
Exercícios
1) Carregue o valor BC21H no registrador AX utilizando:
a) instruções MOV de 8 bits
b) instruções MOV de 16 bits
2) Carregue o valor 71H na posição de memória de dados 075F:0010H utilizando:
a) instruções Assembly
b) comando do Debug
3) Carregue o valor 8CH na posição de memória de dados 075F:0020H de modo indireto (utilizando registrador BX)
4) Construir uma tabela de dados contendo a palavra “IFSP” a partir do endereço de memória de dados 075F:0010H
utilizando instruções Assembly:
5) Estude a instrução XCHG. Quantas instruções MOV são necessárias para realizar a mesma função da instrução
XCHG?
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 13
Experiência 4: Flags e instruções aritméticas do microprocessador x86
Objetivo
Apresentar as instruções aritméticas do microprocessador x86.
Conteúdo
Conforme foi mostrado na Figura 3 o microprocessador possui internamente uma CPU que contém a ULA, responsável
por processar as operações aritméticas quando estas forem solicitadas no programa Assembly. Basicamente, a ULA do
x86 é capaz de processar as seguintes operações aritméticas:
a) Adição (instruções ADD operando1,operando 2)
Efetua a soma aritmética de dois operandos. O resultado é armazenado no operando à esquerda. O operando à direita
permanece inalterado.
Ex: Somar o conteúdo do registrador AX com o conteúdo do registrador BX
ADD AX,BX ; realiza AX = AX + BX
Vamos analisar com mais detalhes a instrução ADD consultando as informações referentes a ela no Anexo II (lista de
instruções Assembly do x86), conforme ilustra a Figura 10.
Figura 10: Descrição da instrução ADD do microprocessador x86
A primeira coluna (Instrução) diz respeito ao código que identifica a instrução (neste caso, ADD).
A segunda coluna (Operandos) diz respeito às variações possíveis dos operandos que esta instrução pode receber.
Conforme pode ser observado, esta instrução permite a soma registro+memória (ex: ADD AX,[0]), memória+registro
(ex: ADD [0],AX), registro+registro (ex: ADD AX,BX) e registro+valor imediato (ex: ADD AX,1234).
A terceira coluna (Descrição) diz respeito a algumas informações relevantes a execução da função. Geralmente inicia
com uma breve descrição de seu objetivo (Soma aritmética). A seguir é representada em formato de microcódigo a
lógica executada pela instrução (operando1 ← operando1 + operando2). Portanto, admitindo que a instrução em questão
fosse ADD AX,BX o conteúdo do registro AX (operando1) seria somado ao conteúdo do registro BX (operando2) e o
resultado armazenado em AX (operando1). Posteriormente é apresentado um exemplo de programa utilizando a
instrução. Por fim, é mostrado em uma pequena tabela as flags que são afetadas por esta instrução.
As flags são bits especiais cujo objetivo é sinalizar alguns status específicos da CPU. O processador x86 possui 8 flags,
representadas na Figura 11, identificadas por 2 letras (blocos vermelhos). No Debug é possível visualizar seus status
através do comando R.
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 14
Figura 11: Flags do microprocessador x86
A seguir segue uma breve descrição das principais flags que serão utilizadas em nossas aulas:
Signal flag (SF): indica que a última instrução gerou um resultado positivo (PL) ou negativo (NG)
Zero flag (ZF): indica que a última instrução gerou um resultado igual a zero (ZR) ou diferente de zero (NZ)
Auxiliary flag (AF): indica que a última instrução gerou um carry bit intermediário (AC) do quarto bit mais
significativo, ou que não gerou um carry bit intermediário (NA)
Parity flag (PF): indica que a última instrução gerou um resultado com quantidade par de “1s” (PE), ou um resultado
com quantidade impar de “1s” (PO)
Carry flag (CF): indica que a última instrução gerou um carry bit (CY) no bit mais significativo, ou que não gerou um
carry bit (NC).
Por exemplo, admitindo que através do comando R obtemos:
AX=1280 BX=2F82 CX=0500 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=077A ES=077A SS=077A CS=077A IP=0100 NV UP EI PL ZR AC PE CY
077A:0100 01D8 ADD AX,BX
Executando a instrução ADD AX,BX através do comando T obtemos:
AX=4202 BX=2F82 CX=0500 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=077A ES=077A SS=077A CS=077A IP=0102 NV UP EI NG NZ NA PO NC
077A:0102 0000 ADD [BX+SI],AL
A operação realizada foi:
111 1111 ; carry bits
0001 0010 1000 0000 ; 1280H (registro AX)
+ 0010 1111 1000 0010 ; 2F82H (registro BX)
----------------------
0100 0010 0000 0010 ; 4202H (registro AX)
Devido a isto, após a execução da instrução:
- Signal flag (SF): a operação gerou um valor positivo (PL)
- Zero flag (ZF): a operação gerou um resultado no registro AX diferente de zero (NZ)
- Auxiliary flag (AF): a operação não gerou um carry bit intermediário (NA)
- Parity flag (PF): a operação gerou um resultado no registro AX com quantidade de “1s” igual a três, é impar (PO)
- Carry flag (CF): a operação não gerou um carry bit no bit mais significativo (NC)
Outra variação da instrução ADD é a instrução ADC, que leva em consideração o resultado do carry bit da instrução
anterior.
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 15
b) Subtração (instruções SUB operando1,operando2)
Efetua a subtração aritmética de dois operandos. O resultado é armazenado no operando à esquerda. O operando à
direita permanece inalterado.
Ex: Subtrair o conteúdo do registrador AX com o conteúdo do registrador BX
SUB AX,BX ; realiza AX = AX - BX
Outra variação da instrução SUB é a instrução SBB, que leva em consideração o resultado do borrow bit da instrução
anterior.
c) Incremento (instrução INC operando)
Soma 1 ao operando especificado, sem afetar o Carry Flag (CF).
Ex: Incrementar o conteúdo do registrador AX.
INC AX ; realiza AX = AX + 1
d) Decremento (instrução DEC operando)
Subtrai 1 do operando especificado, sem afetar o Carry Flag (CF).
Ex: Decrementar o conteúdo do registrador BX.
DEC AX ; realiza AX = AX + 1
e) Multiplicação (instrução MUL operando)
Efetua a multiplicação sem sinal de dois operandos. Para multiplicações de 8 bits x 8 bits o primeiro operando deve ser
AL e o resultado será armazenado em AX. Para multiplicações de 16 bits x 16 bits o primeiro operando deve ser AX e o
resultado será armazenado em DX (parte alta) e em AX (parte baixa).
Ex: Multiplicar o conteúdo do registrador AL pelo conteúdo do registrador BH.
MUL BH ; realiza AX = AL x BH
f) Divisão (instrução DIV operando)
Efetua a divisão sem sinal. Para divisões de um número de 32 bits por um número de 16 bits o dividendo será a
concatenação de DX:AX, o divisor será o operando, o quociente será armazenado no registro AX e o resto será
armazenado no registro DX, ou seja:
(dividendo) DX:AX |__operando__ (divisor)
(resto) DX AX (quociente)
Ex: Dividir o valor 9 por 2.
MOV DX, 0 ; carrega o par DX:AX (dividendo) com o valor 0000 0009H
MOV AX, 9
MOV BX, 2 ; carrega BX (divisor) com o valor 0002H
DIV BX ; realiza DX:AX ÷ BX, com quociente em AX e resto em DX
Após a execução do programa os valores dos registros serão:
AX=0004 BX=0002 CX=0000 DX=0001 SP=FFFE BP=0000 SI=0000 DI=0000
DS=075F ES=075F SS=075F CS=075F IP=0110 NV UP DI PL NZ NA PO NC
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 16
g) Números negativos (instrução NEG operando)
Efetua o complemento de dois no operando especificado. Ou seja, muda o sinal do número ali armazenado.
Ex: Inverter o sinal do valor armazenado no registrador AX (supondo 1234H = 4660D)
NEG AX ; executa o complemento 2 em AX
0001 0010 0011 0100 -> 1234H = 4660D
-------------------
1110 1101 1100 1011 -> EDCBH = 1234H (complemento 1)
1 +
-------------------
1110 1101 1100 1111 -> EDCFH = -4660D (complemento 2)
Exercícios
1) Fazer um programa que some 32H com 27H, subtraia 10H desse resultado e armazene o resultado final incrementado
de 1 na posição DS:0020H da memória de dados.
2) Fazer um programa que some o conteúdo das posições de memória de dados DS:0020H e DS:0021H e guarde o
resultado nas posições de memória DS:0022H (parte alta) e DS:0023H (parte baixa).
3) Admitindo que um valor de 16 bits esteja armazenado nas posições de memória de dados DS:0000H (parte alta) e
DS:0001H (parte baixa) e que outro valor de 16 bits esteja armazenado em DS:0002H (parte alta) e DS:0003H (parte
baixa) fazer um programa, utilizando somente operações de soma de 8 bits + 8 bits e de movimentação, que some estes
dois valores e armazene o resultado a partir do endereço de memória de dados DS:0004H.
4) Fazer um programa que realize a subtração entre dois números positivos contidos nos registradores AX e BX ( ou
seja AX – BX) sem utilizar as instruções SUB e SBB.
5) Fazer um programa que some dois valores positivos de 32 bits.
Desafio
Fazer um programa que calcule o delta de uma equação do 2º grau dada por:
(DS:0000H).x2 + (DS:0001H).x + (DS:0002H) = 0
Admita que os valores inseridos nas posições de memória sejam sempre positivos.
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 17
Experiência 5: Instruções lógicas do microprocessador x86
Objetivo
Apresentar as instruções lógicas do microprocessador x86.
Conteúdo
Conforme foi mostrado na Figura 3 o microprocessador possui internamente uma CPU que contém a ULA, responsável
por processar as operações lógicas quando estas forem solicitadas no programa Assembly. Basicamente, a ULA do x86
é capaz de processar as seguintes operações lógicas:
a) Lógica AND (instrução AND operando1,operando2)
Executa a lógica AND, bit a bit, entre dois operandos. O resultado é armazenado no operando à esquerda. O operando à
direita permanece inalterado.
Ex: Executar a lógica AND entre os registradores AX (contendo F527H) e BX (contendo 5798H).
AND AX,BX ; realiza AX = AX and BX
Ou seja:
AX F527 1111 0101 0010 0111
BX 5798 0101 0111 1001 1000 and
-------------------------------
AX 5500 0101 0101 0000 0000
Esta lógica é muito interessante quando desejamos fazer uma mask (máscara) para zerar determinados bits.
Ex: Zerar os dois bits menos significativos de AX.
AND AX,FFFC ; realiza AX = AX and mask
AX xxxx xxxx xxxx xxxx xxxx
mask FFFC 1111 1111 1111 1100 and
---------------------------------
AX xxxx xxxx xxxx xx00
b) Lógica OR (instrução OR operando1,operando2)
Executa a lógica OR, bit a bit, entre dois operandos. O resultado é armazenado no operando à esquerda. O operando à
direita permanece inalterado.
Ex: Executar a lógica OR entre o registrador AX e o valor 123BH.
OR AX,123B ; realiza AX = AX or 123B
Esta lógica é muito interessante quando desejamos fazer uma mask para setar determinados bits.
Ex: Setar os dois bits mais significativos de AX.
OR AX,C000 ; realiza AX = AX or mask
AX xxxx xxxx xxxx xxxx xxxx
mask C000 1100 0000 0000 0000 or
---------------------------------
AX 11xx xxxx xxxx xxxx
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 18
c) Lógica NOT (instrução NOT operando)
Efetua a lógica NOT bit a bit no operando. O resultado é armazenado no próprio operando.
Ex: Inverter todos os bits do valor armazenado no registrador BX.
NOT BX ; realiza BX = not BX
d) Lógica XOR (instrução XOR operando1,operando2)
Efetua a lógica XOR (eXclusive OR) bit a bit entre dois operandos. O resultado é armazenado no operando à esquerda.
O operando à direita permanece inalterado.
Ex: Executar a lógica XOR entre os registradores AX e BX.
XOR AX,BX ; realiza AX = AX xor BX
Esta lógica é muito interessante quando desejamos fazer uma mask para inverter o valor de determinados bits. Nesta
mask as posições com valor 1 terão seu valor invertido e as posições com valor 0 terão seu valor mantido.
Ex: Inverter os dois bits menos significativos do registrador AX.
XOR AX,0003 ; realiza AX = AX xor mask
AX uuuu uuuu uuuu uuuu uuuu
mask 0003 0000 0000 0000 0011 xor
---------------------------------
AX uuuu uuuu uuuu uuūū
Além das operações lógicas existem também algumas operações de manipulações de bits. As principais são:
a) Operação de rotação à direita (instrução ROR operando1,operando2)
Efetua a rotação a direita dos bits do operando1. O total de bits a rotacionar é dado pelo valor do operando2. O
resultado é armazenado no operando1. A cada rotação o bit à direita é transferido para o bit à esquerda do resultado. O
operando2 poder ser o valor 1 (para uma única rotação) ou o registrador CL.
Ex: Rotacionar o conteúdo do registrador AX (supondo 1232H) dois bits para a direita.
MOV CL,2 ; carrega a qtde de rotacoes a ser realizada em AX
ROR AX,CL ; realiza AX = AX >> 2
AX (antes) 0001 0010 0011 0010
AX (depois) 1000 0100 1000 1100
Existe ainda a instrução RCR que considera o carry bit da operação anterior no processo de rotação.
b) Operação de rotação à esquerda (instrução ROL operando1,operando2)
Efetua a rotação a esquerda dos bits do operando1. O total de bits a rotacionar é dado pelo valor do operando2. O
resultado é armazenado no operando1. A cada rotação o bit à esquerda é transferido para o bit à direita do resultado. O
operando2 poder ser o valor 1 (para uma única rotação) ou o registrador CL.
Ex: Rotacionar o conteúdo do registrador AX (supondo 1232H) três bits para a esquerda.
MOV CL,3 ; carrega a qtde de rotacoes a ser realizada em AX
ROL AX,CL ; realiza AX = AX << 3
Existe ainda a instrução RCL que considera o carry bit da operação anterior no processo de rotação.
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 19
Exercícios
1) Fazer um programa em Assembly que leia um número na posição de memória DS:0000H, considerando seu bit mais
significativo como sendo o 1º bit e o bit menos significativo como sendo o 8º bit:
a) armazene em DS:0001H o número com seu 3º bit setado
b) armazene em DS:0002H o número com seu 2º bit zerado
c) armazene em DS:0003H o número com seus 1º e 4º bits invertidos
d) armazene em DS:0004H o número rotacionado 3 bits a direita
e) armazene em DS:0005H o número rotacionado 2 bits a esquerda
2) Utilize as instruções SHL ou SHR no lugar das instruções ROL ou ROR para implementar os itens d) e e) do
exercício 1. Qual a diferença entre estas instruções?
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 20
Experiência 6: Instruções de desvio do microprocessador x86
Objetivo
Apresentar as instruções responsáveis por implementar os desvios condicionais e os desvios incondicionais de execução
do programa no microprocessador x86.
Conteúdo
Um dos recursos mais poderosos de se implementar nos programas é a capacidade de alterar a sua sequência de
execução durante a sua própria execução. Chamamos isto de desvio ou salto (branch) do programa. Basicamente podem
ser implementadas de três formas: desvio incondicional, desvio condicional e chamada de subrotina. Os dois primeiros
serão explorados nesta experiência. O terceiro será abordado na experiência seguinte.
1) Desvio incondicional
A sequência de execução é alterada sem analisar qualquer condição
a) Instrução JMP endereco
Efetua um salto incondicional para o endereço da memória de programa composto pelo par CS:endereço.
Ex: efetuar um salto incondicional do programa para o endereço de memória de programa 075F:0150H.
MOV CS,075F
JMP 0150
2) Desvio condicional
As instruções de desvio condicional trabalham analisando diretamente o estado dos flags da última operação realizada
pelo processador e desviam a execução do programa para um determinado endereço se o resultado for verdadeiro. Estes
desvios condicionais, pela própria natureza de sua aplicação e devido ao projeto do processador, saltam apenas de forma
relativa e limitada a 127 posições de endereço de programa para cima ou 127 posições de endereço de programa para
baixo. Caso seja necessário um salto maior é possível faze-lo através de um salto que atinja diretamente uma instrução
de salto incondicional JMP.
Antes de analisarmos as instruções de desvio condicional é interessante analisarmos uma outra instrução muito comum
de ser utilizada antes destas: a instrução CMP.
Instrução CMP operando1,operando2
Esta instrução executa a subtração operando1 – operando2, descartando o resultado desta subtração e afetando somente
os flags correspondentes.
Ex: Comparar os conteúdos dos registradores AL e BL
MOV AL,5 ; AL = 5
MOV BL,5 ; BL = 5
CMP AL,BL ; AL e BL não alteram seu valor e flag ZF = ZR (resultado zero)
a) Instrução JE endereco
Salta se o operando1 for igual ao operando2 (de acordo com o resultado da instrução CMP)
Ex: Comparar se os conteúdos dos registradores AX e BX são iguais.
CMP AX,BX ; compara AX e BX
JE 150 ; salta para CS:0150H se AX=BX, caso contrario o programa segue
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 21
b) Instrução JNE endereço
Salta se o operando1 não for igual ao operando2 (de acordo com o resultado da instrução CMP)
c) Instrução JL endereço
Salta se o operando1 for menor que o operando2 (de acordo com o resultado da instrução CMP)
d) Instrução JNL endereço
Salta se o operando1 não for menor que o operando2 (de acordo com o resultado da instrução CMP)
e) Instrução JLE endereço
Salta se o operando1 for menor ou igual ao operando2 (de acordo com o resultado da instrução CMP)
f) Instrução JNLE endereço
Salta se o operando1 não for menor e não for igual ao operando2 (de acordo com o resultado da instrução CMP)
g) Instrução JB endereço
Salta se o operando1 estiver abaixo do operando2 (de acordo com o resultado da instrução CMP).
h) Instrução JNB endereço
Salta se o operando1 não estiver abaixo do operando2 (de acordo com o resultado da instrução CMP).
i) Instrução JBE endereço
Salta se o operando1 estiver abaixo ou for igual ao operando2 (de acordo com o resultado da instrução CMP).
j) Instrução JNBE endereço
Salta se o operando1 não estiver abaixo e não for igual ao operando2 (de acordo com o resultado da instrução CMP).
k) Instrução JP endereço
Salta se o resultado anterior tiver paridade par. Somente os 8 bits menos significativos do resultado serão analisados (de
acordo com o resultado das instruções CMP, SUB, ADD, TEST, AND, OR e XOR).
l) Instrução JNP endereço
Salta se o resultado anterior não tiver paridade par. Somente os 8 bits menos significativos do resultado serão analisados
(de acordo com o resultado das instruções CMP, SUB, ADD, TEST, AND, OR e XOR).
Ex: Saltar para o endereço da memória de programa CS:0150H se o valor contido no registrador AL não tiver paridade
par.
ORL AL,0 ; instrução para setar/resetar flags sem alterar valor de AL
JNP 150 ; saltar se AL não tiver paridade par
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 22
m) Instrução JO endereço
Salta se a flag de overflow estiver setada (flag OF = OV).
n) Instrução JNO endereço
Salta se a flag de overflow não estiver setada (flag OF = NV).
o) Instrução JS endereço
Salta se o resultado for um número negativo (de acordo com o resultado das instruções CMP, SUB, ADD, TEST, AND,
OR e XOR).
p) Instrução JNS endereço
Salta se o resultado for um número positivo (de acordo com o resultado das instruções CMP, SUB, ADD, TEST, AND,
OR e XOR).
Exercícios
1) Fazer um programa que analise se o número inserido dentro do registro AX é par ou impar. O resultado da análise
deve ser mostrado com um caracter ASCII no endereço de memória de dados 075F:0000H. Caso seja par será mostrado
o caracter “P”. Caso seja ímpar será mostrado o caracter “I”.
2) Fazer um programa que analise se o número inserido dentro do registro AL tem paridade par ou impar. Caso seja
ímpar o valor de BX será 1, caso seja par o valor de BX será 2, e caso seja zero o valor de BX será zero.
3) Fazer um programa que analise a nota de um aluno (inserido dentro do registro AX) e escreva uma mensagem em
caracter ASCII a partir do endereço de memória de dados 075F:0000H. Caso a nota seja menor que 4,0 escreva a
mensagem “reprovado”, caso a nota seja 4,0 ≤ nota < 6,0 escreva a mensagem “exame” e caso a nota seja igual ou
superior a 6,0 escreva a mensagem “aprovado”.
4) Existem ainda outras instruções alternativas para desvio que são equivalentes a algumas das instruções mencionadas.
O quadro abaixo ilustra estas instruções.
Instrução original Instrução alternativa
JE endereço JZ endereço
JNE endereço JNZ endereço
JL endereço JNGE endereço
JNL endereço JGE endereço
JLE endereço JNG endereço
JNLE endereço JG endereço
JB endereço JNAE endereço
JNB endereço JAE endereço
JBE endereço JNA endereço
JNBE endereço JÁ endereço
JP endereço JPE endereço
JNP endereço JPO endereço
Analise cada uma das instruções e verifique se os programas anteriormente feitos podem ter suas instruções originais
substituídas pelas instruções alternativas.
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 23
Experiência 7: Stack memory e subrotinas no microprocessador x86
Objetivo
Apresentar os conceitos de stack memory e chamadas de sub-rotinas no microprocessador x86.
Conteúdo
A stack memory é um recurso muito comum em sistemas microprocessados que permite ao usuário salvar e reaver
dados em uma estrutura chamada pilha de memória. O procedimento é semelhante ao processo de armazenar várias
folhas de papel (dados) em uma pilha de papel (stack memory). Armazenamos na pilha de papeis folha de papel sobre
folha de papel. Para reaver uma folha de papel temos de iniciar pela última folha armazenada no topo da pilha.
No microprocessador x86 utilizamos os registradores SS, SP, endereços de memória de dados e as instruções assembly
PUSH e POP. Supondo que após um comando R do Debug temos:
AX=AABB BX=0000 CX=0000 DX=0000 SP=00FF BP=0000 SI=0000 DI=0000
DS=075F ES=075F SS=075F CS=075F IP=0100 NV UP EI PL ZR AC PE CY
075F:0100 50 PUSH AX
Antes de executar a instrução PUSH AX teremos a seguinte estrutura, ilustrada pela Figura 12. Nesta estrutura, o par
SS:SP define um ponteiro que aponta para o endereço de memória referente ao topo da stack memory.
Figura 12: Estrutura da stack memory antes da execução da instrução PUSH AX
Após a execução da instrução PUSH AX teremos a seguinte estrutura, ilustrada pela Figura 13, onde o processador
copia os bytes que compõem o valor armazenado no registro AX e os armazena na pilha, no formato little-endian.
Figura 13: Estrutura da stack memory após da execução da instrução PUSH AX
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 24
Para reaver a informação salva na pilha de memória basta executar a instrução POP em conjunto com o registro no qual
será armazenada a informação. Neste caso, como salvamos o registro AX, para reaver seu conteúdo basta executar:
POP AX
Outro recurso também comum de ser encontrado é o uso de subrotinas. Subrotinas são um conjunto de instruções que,
normalmente, deseja-se que sejam executadas várias vezes durante um determinado programa. Seu funcionamento é
semelhante aos desvios de programa mostrados na experiência anterior, com a diferença que a chamada de uma
subrotina oferece recursos adicionais que permitem o retorno do programa no ponto de chamada da subrotina em
conjunto com o recurso de stack memory.
No microprocessador x86 utilizamos os registradores SS, SP, endereços de memória de dados e as intruções assembly
CALL e RET. Supondo que desejamos executar em um determinado programa diversas vezes a soma entre os registros
AX e BX. Neste caso, pode-se disponibilizar a soma entre esses registros através de uma subrotina. O código abaixo
ilustra um exemplo de implementação desta subrotina em um programa que se inicia no endereço de memória de
programa 075F:0100H e cuja subrotina de soma entre os dois registros esteja localizado a partir do endereço
075F:0117H.
Vamos admitir que após um comando R do Debug temos:
AX=0000 BX=0000 CX=0000 DX=0000 SP=00FD BP=0000 SI=0000 DI=0000
DS=075F ES=075F SS=075F CS=075F IP=0100 NV UP EI PL ZR AC PE CY
075F:0100 50 PUSH AX
E após um comando U do Debug a partir da memória de programa CS:0100H, temos:
075F:0100 B80100 MOV AX,0001
075F:0103 BB0200 MOV BX,0002
075F:0106 E80E00 CALL 0117
075F:0109 B80300 MOV AX,0003
075F:010C BB0400 MOV BX,0004
075F:010F E80500 CALL 0117
075F:0112 90 NOP
075F:0113 0000 ADD [BX+SI],AL
075F:0115 0000 ADD [BX+SI],AL
075F:0117 01D8 ADD AX,BX
075F:0119 C3 RET
075F:011A 0000 ADD [BX+SI],AL
075F:011C 0000 ADD [BX+SI],AL
Um resumo da ordem de execução deste programa é mostrado a seguir.
MOV AX,0001 → O valor 0001H será armazenado no registro AX.
MOV BX,0002 → O valor 0002H será armazenado no registro BX.
CALL 0117 → É feita a chamada para a subrotina localizada no endereço de memória de programa
CS:0117H. Neste momento o endereço de retorno do programa (075F:0109H) é salvo na
stack memory e o valor do registro IP é alterado para 0117H, o que desvia o programa para o
endereço da memória de programa 075F:0117H.
ADD AX,BX → É feita a soma entre os registros AX e BX
RET → É feito o retorno do programa para o endereço de memória de programa salvo na
stack memory (neste caso 075F:0109H)
MOV AX,0003 → O valor 0003H será armazenado no registro AX.
MOV BX,0004 → O valor 0004H será armazenado no registro BX.
CALL 0117 → É feita a chamada para a subrotina localizada no endereço de memória de programa
CS:0117H. Neste momento o endereço de retorno do programa (075F:0112H) é salvo na
stack memory e o valor do registro IP é alterado para 0117H, o que desvia o programa para o
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 25
endereço da memória de programa 075F:0117H.
ADD AX,BX → É feita a soma entre os registros AX e BX
RET → É feito o retorno do programa para o endereço de memória de programa salvo na
stack memory (neste caso 075F:0112H)
Um último comentário é a respeito da chamada de uma subrotina. Em alguns casos pode ocorrer a situação no qual o
programa principal utilize, por exemplo, alguns registros. E estes mesmos registros, por exemplo, são utilizados
também pela subrotina. Seria interessante que a execução da subrotina fosse transparente para estes registros, ou seja,
após o retorno da subrotina o valor destes registros estivessem com os mesmos valores antes da chamada da subrotina.
Para isto, pode-se utilizar as instruções PUSH no início da subrotina (para salvar os registros desejados) e POP no final
da subrotina (para reaver os registros desejados). O exemplo a seguir exibe um exemplo de subrotina utilizando as
instruções PUSH e POP. Observe a ordem de execução destas instruções, que deve levar em conta o funcionamento do
mecanismo de stack memory.
PUSH AX
PUSH BX
MOV AX,0001
MOV BX,0002
ADD AX,BX
POP BX
POP AX
Exercícios
1) Faça uma subrotina que realize a subtração de dois valores de 8 bits presentes nos endereços de memória 075F:0200H
e 075F:0201H, armazenando o resultado em 075F:0202H, levando em consideração que a subrotina seja transparente.
exemplo:
075F:0200H = numero A
075F:0201H = numero B
após execução da subrotina:
075F:0202H = resultado A - B
2) Faça uma subrotina que altere a letra em código ASCII armazenada no endereço de memória de dados 075F:0200H
de minúscula para maiúscula, levando em consideração que a subrotina seja transparente.
exemplo:
075F:0200H = letra c
após execução da subrotina:
075F:0200H = letra C
3) Faça uma subrotina que calcule a soma de dois números de 16 bits, levando em consideração que a subrotina seja
transparente.
exemplo:
075F:0200H e 075F:0201H → número A (little endian)
075F:0202H e 075F:0203H → número B (little endian)
após a execução da subrotina:
075F:0204H , 075F:0205H e 075F:0206H → resultado A+B (little endian)
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 26
Experiência 8: Prática de programação
Objetivo
Desenvolver e aprimorar a prática de programação de sistemas microprocessados.
Conteúdo
Nesta aula iremos praticar através de exercícios a prática de programação.
Exercícios
1) Fazer um programa em assembly que exiba em caracteres ASCII entre os endereços da memória de dados
075F:0110H e 075F:0112H o valor armazenado na posição de memória de dados 075F:0100H convertido em decimal.
Exemplo:
075F:0100 80 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0110 31 32 38 00 00 00 00 00-00 00 00 00 00 00 00 00 128.............
075F:0120 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0130 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0140 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0150 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
2) Fazer um programa em assembly que simule uma calculadora de 8 bits. Ela funcionará da seguinte forma:
- antes de executar o programa no registro AX será armazenada um valor que corresponde a operação desejada:
0: soma
1: subtração
2: multiplicação
3: divisão
- nos endereços de memória de dados 075F:0100H e 075F:0101H estarão armazenados os dois números que sofrerão a
operação selecionada
- no endereço de memoria de dados 075F:0110H e 05F:0111H serão armazenados o resultado da operação selecionada.
Exemplo: supondo que no registro AX esteja armazenado o valor 0 (soma):
075F:0100 F0 46 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .F..............
075F:0110 01 36 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .6..............
075F:0120 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0130 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0140 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0150 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 27
3) Fazer um programa em assembly que realize a criptografia de uma mensagem de 16 caracteres ASCII armazenada
entre os endereços da memória de dados 075F:0100H e 075F:010FH, exibindo o resultado desta criptografia entre os
endereços da memória de dados 075F:0110H e 075F:011FH. A criptografia a ser aplicada corresponde a somar o valor 2
para cada valor de caracter ASCII.
Exemplo:
075F:0100 54 45 53 54 41 52 20 41-4C 47 4F 52 49 54 4D 4F TESTAR ALGORITMO
075F:0110 56 47 55 56 43 54 22 43-4E 49 51 54 4B 56 4F 51 VGUVCT”CNIQTKVOQ
075F:0120 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0130 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0140 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0150 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
075F:0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
Observação: repare que a operação de criptografia será repetida 16 vezes, portanto, implemente esta operação de
criptografia dentro de uma subrotina que seja transparente.
4) Fazer um programa em assembly que descriptografe a mensagem criptografada no exercício anterior, exibindo o
resultado da mensagem descriptografada entre os endereços da memória de dados 075F:0120H e 075F:012FH
5) Fazer um programa que analise as notas de um aluno. Ele é avaliado através de 4 provas, valendo de zero a dez. As
notas devem ser inseridas da seguinte forma:
075F:0100H = nota da prova P1
075F:0101H = nota da prova P2
075F:0102H = nota da prova P3
075F:0103H = nota da prova P4
O programa deve calcular a média das 4 notas e exibir o resultado na posição de memória 075F:0110H.
O programa também deve escrever uma mensagem em caracteres ASCII a partir do endereço de memória de dados
075F:0120H. Caso a nota seja menor que 4,0 escreva a mensagem “reprovado”, caso a nota seja 4,0 ≤ nota < 6,0 escreva
a mensagem “exame” e caso a nota seja igual ou superior a 6,0 escreva a mensagem “aprovado”.
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 28
Experiência 9: Introdução ao microcontrolador 8051 e ao simulador
EdSim51
Objetivo
Apresentar o microcontrolador 8051 e o simulador EdSim51.
Conteúdo
O microcontrolador 8051 é uma família de microcontroladores desenvolvida pela Intel. Sua estrutura básica é ilustrada
pela Figura 14.
Sua CPU é de base 8 bits, otimizada para aplicações de controle. Sua memória não volátil, responsável por armazenar o
firmware, possui tamanho de 4 Kbytes (com endereçamento de 16 bits e dados de 8 bits). Sua memória volátil possui
tamanho de 128 bytes (com endereçamento de 8 bits e dados de 8 bits). Além disto, possui internamente dispositivos
periféricos com funções de automação. A versão básica conta com 2 timers (temporizadores/contadores) de 16 bits, 1
porta serial (síncrona/assíncrona), 4 ports (portas paralelas) e uma estrutura interna para gerenciamento de interrupções.
Nesta disciplina será abordado somente a estrutura básica de memória e o uso dos ports para acionamento básico de
dispositivos.
Figura 14: Estrutura básica de um microcontrolador 8051
A Figura 15, a seguir, ilustra a estrutura básica da memória de dados interna do 8051. Ela possui no total 256 endereços
(00H a FFH) de 8 bits cada um. Estes endereços são divididos em duas grandes áreas:
- 00H a 7FH: área de memória para uso geral
- 80H a FFH: área de memória para uso especial (SFR – Special Funcion Registers)
Na área de memória para uso geral cada endereço de memória é identificado através de um número de 8 bits (00H a
7FH), conforme ilustra a Figura 16. Nesta área existe ainda uma região inicial (00H a 1FH) onde se localizam os bancos
de registros internos de uso geral. Tais endereços de memória podem ser acessados tanto pelo seu número de endereço
quanto pelo nome de registro que os identificam (R0 a R7). Por exemplo, supondo que se deseje gravar na posição de
memória de dados 01H o valor ABH. Isto pode ser feito de duas formas pela instrução assembly MOV:
MOV 01H, #0ABH ou MOV R1, #0ABH
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 29
Figura 15: Estrutura básica da memória de dados do 8051
Figura 16: Mapa de memória de dados de 00H a 7FH
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 30
Na área de memória de uso especial cada endereço de memória possível de ser utilizado é identificado por um nome,
conforme ilustra a Figura 17.
Figura 17: Mapeamento da memória de dados de uso especial (SFR memory map)
Por exemplo, o acumulador (ACC), que fica localizado no endereço de memória de dados E0H, é acessível pelo nome
ACC. Caso se deseje carregar o valor 75H no acumulador, a seguinte instrução assembly pode ser utilizada:
MOV ACC, #075H
Nesta área de memória localizam-se ainda diversos registros especiais, cujas principais funções são de controlar os
periféricos internos do 8051. Um dos periféricos que iremos utilizar são os ports. Os ports tem a função de gerar uma
interface I/O (Input/Output, ou seja, entrada e saída) digital, permitindo o acionamento (Output) ou a leitura (Input) do
valor digital presente em determinados pinos do 8051.
Para explorar os recursos oferecidos pelo microcontrolador 8051 vamos utilizar nesta disciplina um simulador chamado
EdSim51 (www.edsim51,com), desenvolvido pelo prof. James Rogers, da Institute of Technology Sligo. Este simulador
é interessante porque além de simular todos os dispositivos internos de um microcontrolador 8051 (ports, timers,
memória RAM, serial, etc.) ele possui um editor para programas em assembly simples e é capaz de simular um
hardware externo pré definido, permitindo por exemplo acionar LEDs, conversores analógico digitais, displays de 7
segmentos, etc.
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 31
A Figura 18 ilustra a parte da tela do simulador referente aos registros, memória de dados e editor de programa
assembly.
Figura 18: Tela do simulador EdSim51 (região dos registros, memória e editor de programa)
A Figura 19 ilustra a parte da tela do simulador referente ao hardware externo simulado.
Figura 19: Tela do simulador EdSim51 (região do hardware simulado)
A Figura 20 ilustra o esquema elétrico do hardware externo simulado pelo EdSim51.
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 32
Figura 20: Esquema do hardware simulado pelo EdSim51
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 33
Conforme se pode observar no esquema da Figura 20 o microcontrolador 8051 possui 4 ports de 8 bits:
- port P0 (terminais P0.0 a P0.7)
- port P1 (terminais P1.0 a P1.7)
- port P2 (terminais P2.0 a P2.7)
- port P3 (terminais P3.0 a P3.7)
Para acionarmos os terminais de um determinado port basta escrevermos o valor correspondente no endereço de
memória referente ao port desejado. Por exemplo, observe que no port P1 estão conectados 8 LEDs. Supondo que
desejamos acionar somente o LED7. Para isto, basta escrevermos na posição de memória do port P1 (endereço 90H) o
valor 0111 1111B (ou seja, 7FH) fazendo uso da instrução assembly MOV da seguinte forma:
MOV P1, #07FH
Exercícios
1) Fazer um programa em assembly que acenda os seguintes LEDs:
a) LED1, LED3 e LED7
b) os LEDs pares
2) Fazer um programa em assembly que escreva no display DISP 3 os seguintes caracteres:
a) letra A
b) número 4
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 34
Experiência 10: Introdução às instruções de movimentação e de operação
aritmética no 8051
Objetivo
Introdução sobre as instruções de movimentação e de operação aritmética do microcontrolador 8051.
Conteúdo
O microcontrolador 8051, assim como o sistema microprocessado implementado através do microprocessador x86,
também possui um conjunto de instruções utilizadas para movimentação e para operações aritméticas.
A instrução básica utilizada para movimentação é a instrução MOV, cuja sintaxe é:
MOV <dest-byte>,<src-byte>
Ex: movimentar o conteúdo do registrador R1 para o acumulador
MOV ACC, R1
A instrução aritméticas básicas implementadas na ALU do microcontrolador 8051 são adição, subtração, multiplicação
e divisão:
a) soma
A instrução básica utilizada para soma é a instrução ADD, cuja sintaxe é:
ADD A, <src-byte>
Ex: somar 05H no valor armazenado no acumulador
ADD A, #005H
b) subtração
A instrução básica utilizada para soma é a instrução SUBB, cuja sintaxe é:
SUBB A, <src-byte>
Ex: subtrair 07H no valor armazenado no acumulador
SUBB A, #007H
c) multiplicação
A instrução utilizada para a multiplicação é a instrução MUL, cuja sintaxe é:
MUL AB
A multiplicação, neste caso, sempre ocorre entre os valores armazenados em ACC e B.
d) divisão
A instrução utilizada para a divisão é a instrução DIV, cuja sintaxe é:
DIV AB
A divisão também, neste caso, sempre ocorre entre os valores armazenados em ACC e B.
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 35
Exercícios
1) Fazer um programa que some 32H com 27H, subtraia 10H desse resultado e armazene o resultado final incrementado
de 1 na posição 30H da memória de dados.
2) Fazer um programa que some o conteúdo das posições de memória de dados 20H e 21H e guarde o resultado nas
posições de memória 22H (parte alta) e 23H (parte baixa).
3) Admitindo que um valor de 16 bits esteja armazenado nas posições de memória de dados 30H (parte alta) e 31H (parte
baixa) e que outro valor de 16 bits esteja armazenado em 32H (parte alta) e 33H (parte baixa) fazer um programa que
some estes dois valores e armazene o resultado a partir do endereço de memória de dados 34H:
a) em notação little endian
b) em notação bit endian
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 36
Experiência 11: Introdução à linguagem C e a portabilidade de código em
sistemas microprocessados
Objetivo
Introduzir os conceitos básicos para a programação em Linguagem C de sistemas microprocessados.
Conteúdo
O avanço dos compiladores e das linguagens de programação utilizados para a programação de sistemas
microprocessados permitiu que se utilizassem linguagens de níveis mais altos (com maior abstração do hardware). Uma
das linguagens mais difundidas para a programação de sistemas microprocessados é a Linguagem C.
O código a seguir ilustra um exemplo de programa escrito em linguagem C para o microcontrolador 8051.
#include <at89x51.h>
code unsigned char NUM0 = 0xFE;
data unsigned char Teste;
data unsigned volatile char Teste = 0xFE;
void main(void)
{
P1 = 0x00;
Teste = NUM0;
while (1)
{
Teste = Teste << 1;
P1 = Teste;
}
}
Uma das grandes vantagens de se programar em Linguagem C é a sua portabilidade, ou seja, a possibilidade de
reutilização de um programa feito inicialmente para um modelo de microprocessador/microcontrolador para um outro
modelo, com pequena quantidade de código reescrito. Vamos supor, por exemplo, que desejemos calcular o resultado
da soma entre 03H e 05H:
a) Como seria escrito um programa para realizar esta tarefa em linguagem assembly para o microprocessador x86?
b) Como seria escrito um programa para realizar esta tarefa em linguagem assembly para o microcontrolador 8051?
c) Seria possível reutilizar o código escrito anteriormente no item a) no item b)?
d) Como seria escrito um programa para realizar esta tarefa em Linguagem C para o microprocessador x86?
e) Como seria escrito um programa para realizar esta tarefa em Linguagem C para o microcontrolador 8051?
f) Seria possível reutilizar o código escrito anteriormente no item d) no item e)?
Exercícios
Refaça os exercícios da Experiência 9, utilizando a Linguagem C.
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 37
Experiência 12: Introdução às plataformas IDE para o desenvolvimento de
sistemas microcontrolados
Objetivo
Apresentar o conceito de plataforma IDE e alguns exemplos de plataformas IDE disponíveis no mercado.
Conteúdo
O avanço dos sistemas microprocessados tornou necessária a evolução das ferramentas utilizadas para a programação
dos microcontroladores/microprocessadores. Como resultado desta evolução surgiram softwares chamados de
plataformas IDE (Integrated Development Environment - Ambiente de Desenvolvimento Integrado) cuja finalidade é
integrar, em um único ambiente, o editor de programa, o compilador e o simulador/emulador. Como exemplos destas
plataformas podemos destacar o Keil C51, o MPLAB, o Arduino IDE e o Atollic TrueSTUDIO.
O Keil C51 é uma plataforma IDE desenvolvida pela empresa Keil (www.keil.com) projetada para os
microcontroladores da família 8051.
O MPLAB é uma plataforma IDE desenvolvida pela empresa Microchip (www.microchip.com) projetada para os
microcontroladores de 8 bits, 16 bits e 32 bits (família PIC, dsPIC, PIC32, etc.) desenvolvidos pela empresa.
O Arduino IDE é uma plataforma IDE desenvolvida pelo Ivrea Interaction Design Institute (www.arduino.cc) projetada
para a programação de kits didáticos arduíno que utilizam como base os microcontroladores da família AVR, da
empresa Atmel.
O Atollic TrueSTUDIO é uma plataforma IDE desenvolvida pela empresa Atollic (www.atollic.com) projetada para os
microcontroladores com núcleo ARM de diversos fabricantes, como Freescale, Texas Instrument e ST
Microelectronics.
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 38
Anexo I. Código ASCII
TABELA DE CODIGOS ASCII
Hex Sinal Hex Sinal Hex Sinal
20 (espaço) 40 @ 60 `
21 ! 41 A 61 a
22 " 42 B 62 b
23 # 43 C 63 c
24 $ 44 D 64 d
25 % 45 E 65 e
26 & 46 F 66 f
27 ' 47 G 67 g
28 ( 48 H 68 h
29 ) 49 I 69 i
2A * 4A J 6A j
2B + 4B K 6B k
2C , 4C L 6C l
2D - 4D M 6D m
2E . 4E N 6E n
2F / 4F O 6F o
30 0 50 P 70 p
31 1 51 Q 71 q
32 2 52 R 72 r
33 3 53 S 73 s
34 4 54 T 74 t
35 5 55 U 75 u
36 6 56 V 76 v
37 7 57 W 77 w
38 8 58 X 78 x
39 9 59 Y 79 y
3A : 5A Z 7A z
3B ; 5B [ 7B {
3C < 5C \ 7C |
3D = 5D ] 7D }
3E > 5E ^ 7E ~
3F ? 5F _
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 39
Anexo II: Set de instruções do processador x86
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 40
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 41
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 42
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 43
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 44
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 45
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 46
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 47
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 48
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 49
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 50
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 51
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 52
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 53
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 54
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 55
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 56
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 57
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 58
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 59
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 60
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 61
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 62
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 63
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 64
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 65
Apostila de Laboratório de Microcoprocessadores Prof. Igarashi página 66
Bibliografia
Prof. Gilberto Igarashi – Laboratório de Microcontroladores (Apostila) – IFSP Campus SPO – 2010
Prof. Alexandre Aragão – Laboratório de Microprocessadores (Apostila) – IFSP Campus SPO – 2012
Edsim51 – Simulador de 8051 – Prof James Rogers - Institute of Technology Sligo (www.edsim51.com)
Prof. Kip Irvine – Using Debug (apostila) – Florida International University
(http:;kipirvine.com/asm/debug/debug_tutorial.pdf)
Top Related