MM – Microprocessadores e Microcontroladores – Roteiro da Experiência 5
EXPERIÊNCIA 5 – INSTRUÇÕES DE TRANSFERÊNCIA DE DADOS
Parte I – Fundamentos Teóricos
Nas experiências anteriores, foram utilizadas diversas instruções que executam uma transferência de dados, isto é, que copiam um
dado “fonte” para um “destino”. A Tabela 1 descreve as instruções que fazem transferências de dados com acessos à RAM interna do
8051; na Tabela 2, são descritas as instruções de transferência de dados capazes de acessar a RAM externa; e as instruções que
acessam a memória de programa (código) são descritas na Tabela 3. Nessas tabelas, <dado8>, <fonte8> e <destino8> são valores
de 8 bits, que podem ser obtidos através de um dos modos de endereçamento assinalados por “X”; <valor16> é um valor imediato de
16 bits; e Ri representa o registrador R0 ou o registrador R1.
instrução
operação
modos de endereçamento
direto indireto registrador imediato
X
X
X
X
X
X
X
X
X
X
X
X
ACC  <fonte8>
<destino8>  ACC
<destino8>  <fonte8>
DPTR  <valor16>
SP  SP  1
PUSH <fonte8>
X
mem.int.[SP]  <fonte8>
<destino8>  mem.int.[SP]
X
POP <destino8>
SP  SP  1
X
X
X
XCH A, <dado8>
ACC  <dado8>
XCHD A, @Ri
X
“nibble” inf.(ACC)  “nibble” inf.(mem.int.[Ri])
Tabela 1 – Instruções transferência de dados do 8051, com acesso à RAM interna
MOV A, <fonte8>
MOV <destino8>, A
MOV <destino8>, <fonte8>
MOV DPTR, #<valor16>
A instrução MOV copia o valor fonte no destino. O valor fonte não se altera.
As instruções PUSH e POP fazem acesso à pilha, que é uma área da RAM interna, do tipo “LIFO” (“Last In, First Out”, ou seja,
o último dado inserido será o primeiro a ser retirado), cujo apontador é o registrador SP. Note que esse registrador é incrementado
antes da inserção de um dado, isto é, ele aponta o último dado já inserido, que é o primeiro a ser removido.
A instrução XCH troca os valores do acumulador e de um outro dado, numa única instrução. Já a instrução XCHD troca os
“nibbles” inferiores (4 bits menos significativos) do acumulador e da posição da RAM interna apontada pelo registrador R0 ou R1.
modos de endereçamento
direto indireto registrador imediato
MOVX A, @Ri
X
ACC  mem.ext.[Ri]
X
MOVX @Ri, A
mem.ext.[Ri]  ACC
MOVX A, @DPTR
X
ACC  mem.ext.[DPTR]
X
MOVX @DPTR, A
mem.ext.[DPTR]  ACC
Tabela 2 – Instruções transferência de dados do 8051, com acesso à RAM externa
instrução
operação
A instrução MOVX copia um valor da, ou para a, RAM externa, utilizando o acumulador para essa operação. O modo de
endereçamento é sempre indireto, podendo ser utilizados como apontador os registradores R0, R1 ou DPTR.
modo de endereçamento
indexado
X
MOVC A, @A+DPTR
ACC  mem.prog.[DPTR+A]
MOVC A, @A+PC
X
ACC  mem.prog.[PC+A]
Tabela 3 – Instruções transferência de dados do 8051, com acesso à memória de programa
instrução
operação
A instrução MOVC copia um valor da memória de código para o acumulador (não é possível a escrita nesse memória!). O modo
de endereçamento é sempre indexado, sendo o acumulador o registrador de índice, e o registrador DPTR ou PC o registrador de base.
Parte II – Roteiro Experimental
Carregue, na memória RAM externa, a partir do endereço 5000h, o programa da Tabela 4, digitando seu código de máquina.
pass
o
1
2
3
4
5
6
7
8
9
10
11
endereç
o
5000
5003
5005
5007
5008
500B
500C
500E
500F
5010
5012
código de máquina
75
74
79
F7
90
F0
C0
C9
D7
D0
02
01
01
01
mnemônico e operandos
comentários
MOV SP, #2Fh
SP  2Fh
MOV A, #26h
ACC  26h
MOV R1, #18h
R1  18h
MOV @R1, A
mem.int.[R1]  ACC
38
MOV DPTR, #5038h
DPTR  5038h
MOVX @DPTR, A
mem.ext.[DPTR]  ACC
PUSH 1
SP  SP1; mem.int.[SP]  mem.int.[1] (=R1)
XCH A, R1
ACC  R1
XCHD A, @R1
“nibble” inf.(ACC)  “nibble” inf.(mem.int.[R1])
POP 1
mem.int.[1] (=R1)  mem.int.[SP]; SP  SP1
desvia para o MONITOR
C0
LJMP MONITOR
Tabela 4 – Programa com instruções de transferência de dados
81 2F
26
18
50
rótulo
MM – Microprocessadores e Microcontroladores – Roteiro da Experiência 5
Execute o programa passo a passo, a partir do endereço 5000h (não se esqueça de, antes da execução, carregar o registrador PC
com este valor). A cada instrução executada, leia o respectivo item, preenchendo suas lacunas. Preencha, também, os valores
solicitados na Tabela 5.
1) O ponteiro da pilha (registrador ____) recebe o valor imediato 2Fh. Isso significa que a base da pilha, isto é, a posição do
primeiro dado a ser empilhado, é a posição 2Fh+1=____h, que é a primeira posição da área livre da RAM interna, imediatamente
acima da área dos bits endereçáveis. Se esta instrução não fosse executada, o registrador SP manteria seu valor recebido no “reset”,
que é ____h, e, assim, a base da pilha seria a posição 08h, o que impediria o uso do banco 1 de registradores.
2) O acumulador recebe o valor imediato ____h.
3) O registrador ____ recebe o valor imediato 18h.
4) O registrador ____ endereça, indiretamente, a posição de endereço 18h da RAM interna, que corresponde ao registrador R0 do
banco ___, fazendo com que este registrador receba o valor do acumulador (26h).
5) O registrador DPTR recebe o valor imediato ________h.
6) A posição de endereço 5038h da RAM _______________ (endereçada indiretamente pelo registrador DPTR) recebe o valor do
acumulador (26h).
7) A instrução PUSH faz um “empilhamento”, isto é, coloca um dado numa área da RAM interna (a pilha), na posição apontada
pelo registrador SP. Antes dessa transferência, porém, o ponteiro da pilha é incrementado, pois ele sempre aponta o “topo” da pilha,
isto é, o último dado já inserido nela. O dado a ser empilhado é obtido, obrigatoriamente, por endereçamento direto; no caso, seu
endereço é ___, o que significa que se trata do conteúdo da posição de endereço 01h da RAM interna, correspondente ao
registrador ____ do banco ___.
8) O acumulador e o registrador ____ têm seus conteúdos trocados entre si.
9) Os “nibbles” menos significativos do ________________ e da posição da RAM interna apontada pelo registrador R1
(endereçamento indireto) são trocados entre si.
10) A instrução POP faz o inverso da instrução PUSH, ou seja, obtém o último dado empilhado, posicionado no “_______” da
pilha (na posição apontada pelo registrador ____) e o copia, por endereçamento direto, para a posição de endereço 1 da RAM interna
(registrador R1 do banco 0). Depois dessa transferência, o ponteiro da pilha é ____________________, apontando o novo “topo” da
pilha (consumando a remoção do dado que, anteriormente, ocupava o “topo”).
11) Desvia para o programa Monitor.
passo
endereço da
instrução
1
2
3
4
5
6
5000h
5003h
5005h
5007h
5008h
500Bh
7
8
9
10
mnemônico e operandos
MOV SP, #2Fh
MOV A, #26h
MOV R1, #18h
MOV @R1, A
MOV DPTR, #5038h
MOVX @DPTR, A
PC
(após a execução da
instrução)
valores obtidos
(após a execução da instrução)
h
h
h
h
h
h
SP =
h
ACC =
h
R1 =
h
mem.int.[18h] =
h
DPH =
h DPL =
h DPTR =
mem.ext.[5038h] =
h
SP =
h mem.int.[30h] =
h
500Ch
PUSH 1
h
ACC =
h R1 =
h
ACC =
h R1 =
h
500Eh
h
XCH A, R1
mem.int.[26h] =
h
ACC =
h R1 =
h
500Fh
XCHD A, @R1
h
mem.int.[26h] =
h
SP =
h mem.int.[30h] =
h
5010h
h
POP 1
ACC =
h R1 =
h
Tabela 5 – Resultados da execução do programa com instruções de transferência de dados
h
EXPERIÊNCIA 5 – QUESTÕES ADICIONAIS
1) A instrução do passo 4 (MOV @R1, A) copia o valor do acumulador para a posição da RAM interna apontada por R1. Qual é a
instrução que copia o valor do acumulador para a posição da memória externa apontada por R1?
2) Além do registrador R1, quais outros registradores podem ser utilizados como apontadores para endereçamento indireto? Quais
áreas (RAM interna, RAM externa) podem ser apontadas por cada um desses registradores? (dica: consulte o roteiro da
Experiência 2, Parte I, item a)2), e a questão adicional 6 dessa mesma experiência)
3) Suponha que o conteúdo do acumulador seja um valor X qualquer, e que o conteúdo do registrador R1 seja um valor Y. Sendo
assim, qual o resultado final da execução da seguinte seqüência de instruções?
PUSH
0E0H
empilha acumulador
PUSH
1
empilha R1
POP
0E0H
desempilha acumulador
POP
1
desempilha R1
4) Indique como obter o mesmo resultado da seqüência da questão anterior, através de uma única instrução. (dica: é uma das
instruções desta experiência!)
5) Suponha que você escreveu uma seqüência de instruções (por exemplo, uma “sub-rotina”) que pode ser executada no meio de um
programa qualquer. O problema é que essa seqüência precisa utilizar os registradores R0, R1 e R2, alterando seus valores, e,
possivelmente, esses registradores serão utilizados, também, pelo programa que irá utilizar sua seqüência. É conveniente, portanto,
preservar os valores de R0, R1 e R2, fazendo com que , ao final da execução de sua seqüência, eles sejam os mesmos que eram
quando sua seqüência foi iniciada. Para garantir isso, insira 3 instruções no início da seqüência, e 3 instruções no final. (dica:
utilize a pilha para “salvar” os valores originais dos registradores, e, no final, “restaure-os”).
6) desafio: Sabendo que o programa onde a sua seqüência será inserida utiliza, obrigatoriamente, apenas o banco 0 de registradores,
proponha outra solução para o problema da questão anterior.
Download

EXPERIÊNCIA 1 – RESET + EXECUÇÃO DE PROGRAMAS