|
PROGRAMAÇÃO
ASM
Lição
7 - As
instruções lógicas AND, OR e XOR.
|
Anterior Indice Seguinte |
Nesta
lição vamos falar das
instruções lógicas AND,
OR e XOR. Para
tornar mais
fácil a compreensão desta matéria
vamos usar as chamadas "Tabelas de verdade" para cada uma das
três funções lógicas
utilizadas pelo CPU Z80, onde estão
representadas todas as combinações
possíveis de entrada e a respectiva saída.
Podemos
dizer resumidamente que a função
lógica AND (Função
"E" em português) só apresenta
a saída ao nível "1" quando todas as entradas
forem "1". Observe a seguir as tabelas de verdade para clarificar o que
foi dito atrás:
Tabela
de Verdade "AND" |
Entrada
A |
Entrada
B |
Saída |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
No caso da função OR
("OU" em português) a saída
é "1" se qualquer das entradas for "1".
Tabela
de Verdade "OR" |
Entrada
A |
Entrada
B |
Saída |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
Por ultimo temos a
função XOR ("OU
exclusivo" em português) onde a saída
é igual a "1" se as entradas forem diferentes uma da outra,
caso contrario a saída é "0".
Tabela
de Verdade "XOR" |
Entrada
A |
Entrada
B |
Saída |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
0 |
Na explicação que
vamos fazer nas próximas lições sobre
as instruções ASM do Z80,
utilizaremos algumas letras com os significados que passamos a
descrever:
- r - Registos de 8 bits (B,
C, D, E,
H,
L, A)
- n
- Numero de 8 bits (0 a 255)
- rr - Registos de 16 bits (BC,
DE, HL, AF)
- ss - Registos de 16 bits (BC,
DE, HL, SP)
- nn - Numero de 16 bits (0 a
65535)
- dis - Deslocamento de 7 bits
com sinal
(-128 a +127)
- x -
Posição do Bit
no Byte (0 a 7, os Bits são numerados da direita para a
esquerda, o bit mais à direita é o "0" e o mais
à esquerda o "7")
Voltando ao tópico
desta lição podemos acrescentar que as
instruções lógicas só usam
registos de 8 bits e números
também de 8 bits. Além disso
as operações são sempre realizadas
entre o registo A e os restantes registos, sendo o
resultado do calculo guardado no registo A (por
isso mesmo é que se chama a este registo de Acumulador).
Vejamos um programa onde se usa a operação
lógica AND.
LD |
A,01101011 |
;Carregamos
o numero 107 representado em binário no registo A |
LD |
B,11100111 |
;Carregamos
o numero 231 também em binário no registo B |
AND |
B |
;Executamos
a função lógica AND entre o registo A
e o B.
;O resultado é guardado em A. |
|
Vamos
fazer as contas mostradas na tabela de
verdade da função AND. |
|
Nº
Bits= |
76543210 |
Um byte tem 8 bits,
numerados de 7 a 0 (da esquerda para a direita). |
--------------
|
----------------- |
|
Registo
A= |
01101011 |
Valor de A em
binário. |
Registo
B= |
11100111 |
Valor de B em
binário. |
--------------
|
----------------- |
|
A
AND B= |
01100011 |
O resultado do calculo
é guardado no
registo A. |
As funções
lógicas são realizadas entre os bits de igual
peso, por outras palavras, o calculo é feito entre o bit
0 do registo A e o bit 0
do registo B, depois segue-se o bit 1
do registo A com o bit 1 do registo
B, terminando no bit 7 de ambos os
registos. Não é necessário mostrar
mais exemplos de calculo para as outras operações
lógicas OR e XOR.
Basta seguir o mesmo raciocínio que foi aplicado na
instrução AND e utilizar as
Tabelas de Verdade correspondentes às
funções lógicas OR
e XOR respectivamente.
Continuando o nosso curso vamos mostrar
em pormenor as instruções lógicas
usadas pelo CPU Z80. Para podermos calcular o
Opcode das instruções do Z80,
atribuímos aos registos de 8 bits e de 16 bits os seguintes
valores:
Registos
8 bits |
Registos 16 bits |
------------------------------ |
------------------------------ |
B=0 |
BC=0 |
C=1 |
DE=1 |
D=2 |
HL=2 |
E=3 |
AF=3 |
H=4 |
SP=3 |
L=5 |
|
A=7 |
|
Vamos
ainda, antes de apresentar as
instruções lógicas, mostrar a
estrutura do registo das FLAGS, visto ser o registo
mais importante do CPU porque é em torno dele que
são projectadas todas as outras
instruções.
Estrutura do
registo de FLAGS (registo
F) |
Bits |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Flags |
S |
Z |
- |
H |
- |
P/V |
N |
C |
- S - Flag de Sinal (Sign
flag).
É colocada a "1" se o bit de maior peso (bit 7 ou 15) do
resultado for "1"
- Z - Flag de
Zero (Zero flag). É colocada a "1" se o resultado for "0"
- H - Flag de transporte
intermédio (Half Carry flag). É colocada a "1" se
ocorreu transporte entre o bit 3 e o bit 4 do resultado, por outras
palavras, se o resultado foi maior que 15
- P/V
- Flag de paridade ou de transbordamento de dados (Parity or Overflow
flag)
- N - Flag de
subtracção (Subtract flag). É colocada
a "1" se a ultima operação realizada foi uma
subtracção
- C
- Flag de transporte (Carry flag). É colocada a "1" se o
resultado não couber no registo destino
Das 6 flags vistas , a Z
e a C são as mais usadas. Nas
descrições das instruções
ASM que vamos fazer, utilizaremos o asterisco "*" para indicar que a
flag é alterada de acordo com o resultado da
operação. A Flag P/V
é "1" se o nº de bits que estão a "1" no
resultado for PAR ou se o resultado for "0", caso
contrario é "0". Vejamos então o formato da
instrução AND r.
Instrução: |
AND r |
Propósito: |
Executa
a
operação lógica AND
entre o registo A e um dos registos
de 8
bits B, C, D, E, H, L, A |
OpCode: |
160
+ r |
Ciclos: |
4 |
Bytes: |
1 |
Flags: |
S=*,
Z=*, H=1, P/V=*, N=0, C=0 |
Por
exemplo a
instrução AND H tem como
Opcode 160+H=160+4=164. Nas características da
instrução o parâmetro
Ciclos refere-se aos ciclos de relógio
necessários para executa-la. Quanto mais ciclos forem usados
mais demora a sua execução. As
instruções mais rápidas necessitam de
4 ciclos para serem executadas. Outro parâmetro importante
refere-se ás Flags,
estas são afectadas em função do
resultado dos cálculos realizados, permitindo executar as
instruções de salto condicionais.
Instrução: |
AND n |
Propósito: |
Executa
a
operação lógica AND
entre o registo A e um numero de 8 bits |
OpCode: |
230,
n |
Ciclos: |
7 |
Bytes: |
2 |
Flags: |
S=*,
Z=*, H=1, P/V=*, N=0, C=0 |
Instrução: |
AND (HL) |
Propósito: |
Executa
a
operação lógica AND
entre o registo A e o endereço de
memoria indicado pelo registo HL |
OpCode: |
166 |
Ciclos: |
7 |
Bytes: |
1 |
Flags: |
S=*,
Z=*, H=1, P/V=*, N=0, C=0 |
Instrução: |
AND
(IX+dis) |
Propósito: |
Executa
a
operação lógica AND
entre o registo A e o endereço de
memoria indicado pelo registo IX mais 1
deslocamento de -128 a +127 |
OpCode: |
221,
166, dis
|
Ciclos: |
19 |
Bytes: |
3 |
Flags: |
S=*,
Z=*, H=1, P/V=*, N=0, C=0 |
Instrução: |
AND
(IY+dis) |
Propósito: |
Executa
a
operação lógica AND
entre o registo A e o endereço de
memoria indicado pelo registo IY mais 1
deslocamento de -128 a +127 |
OpCode: |
253,
166, dis
|
Ciclos: |
19 |
Bytes: |
3 |
Flags: |
S=*,
Z=*, H=1, P/V=*, N=0, C=0 |
Estas
são todas as
instruções AND que existem
para o CPU Z80. As duas ultimas usam os registos de
índice IX e IY.
Pode-se observar que o seu tempo de execução
é muito superior ás outras
instruções, isso deve-se ao facto de ser usado um
deslocamento (displacement)para formar o
endereço efectivo de memoria. Todas as
instruções que usam o registo HL
podem também usar os registos índice IX
e IY, desde que se coloque um prefixo antes do
código da instrução. Para o registo IX
usa-se o prefixo 221 enquanto que para o IY o
prefixo é o 253, evidentemente que, se estamos a utilizar um
compilador não precisamos de preocupar-nos com esse
assunto. As restantes
instruções lógicas OR
e XOR têm os mesmos formatos da
instrução AND. Vamos
então analisa-las.
Instrução: |
OR r |
Propósito: |
Executa
a
operação lógica OR
entre o registo A e um dos registos
de 8
bits B, C, D, E, H, L, A |
OpCode: |
176
+ r |
Ciclos: |
4 |
Bytes: |
1 |
Flags: |
S=*,
Z=*, H=0, P/V=*, N=0, C=0 |
Instrução: |
OR n |
Propósito: |
Executa
a
operação lógica OR
entre o registo A e um numero de 8 bits |
OpCode: |
246,
n |
Ciclos: |
7 |
Bytes: |
2 |
Flags: |
S=*,
Z=*, H=0, P/V=*, N=0, C=0 |
Instrução: |
OR (HL) |
Propósito: |
Executa
a
operação lógica OR
entre o registo A e o endereço de
memoria indicado pelo registo HL |
OpCode: |
182 |
Ciclos: |
7 |
Bytes: |
1 |
Flags: |
S=*,
Z=*, H=0, P/V=*, N=0, C=0 |
Instrução: |
OR
(IX+dis) |
Propósito: |
Executa
a
operação lógica OR
entre o registo A e o endereço de
memoria indicado pelo registo IX mais 1
deslocamento de -128 a +127 |
OpCode: |
221,
182, dis
|
Ciclos: |
19 |
Bytes: |
3 |
Flags: |
S=*,
Z=*, H=0, P/V=*, N=0, C=0 |
Instrução: |
OR
(IY+dis) |
Propósito: |
Executa
a
operação lógica OR
entre o registo A e o endereço de
memoria indicado pelo registo IY mais 1
deslocamento de -128 a +127 |
OpCode: |
253,
182, dis
|
Ciclos: |
19 |
Bytes: |
3 |
Flags: |
S=*,
Z=*, H=0, P/V=*, N=0, C=0 |
Instrução: |
XOR r |
Propósito: |
Executa
a
operação lógica XOR
entre o registo A e um dos registos
de 8
bits B, C, D, E, H, L, A |
OpCode: |
168
+ r |
Ciclos: |
4 |
Bytes: |
1 |
Flags: |
S=*,
Z=*, H=0, P/V=*, N=0, C=0 |
Instrução: |
XOR n |
Propósito: |
Executa
a
operação lógica XOR
entre o registo A e um numero de 8 bits |
OpCode: |
238,
n |
Ciclos: |
7 |
Bytes: |
2 |
Flags: |
S=*,
Z=*, H=0, P/V=*, N=0, C=0 |
Instrução: |
XOR (HL) |
Propósito: |
Executa
a
operação lógica XOR
entre o registo A e o endereço de
memoria indicado pelo registo HL |
OpCode: |
174 |
Ciclos: |
7 |
Bytes: |
1 |
Flags: |
S=*,
Z=*, H=0, P/V=*, N=0, C=0 |
Instrução: |
XOR
(IX+dis) |
Propósito: |
Executa
a
operação lógica XOR
entre o registo A e o endereço de
memoria indicado pelo registo IX mais 1
deslocamento de -128 a +127 |
OpCode: |
221,
174, dis
|
Ciclos: |
19 |
Bytes: |
3 |
Flags: |
S=*,
Z=*, H=0, P/V=*, N=0, C=0 |
Instrução: |
XOR
(IY+dis) |
Propósito: |
Executa
a
operação lógica XOR
entre o registo A e o endereço de
memoria indicado pelo registo IY mais 1
deslocamento de -128 a +127 |
OpCode: |
253,
174, dis
|
Ciclos: |
19 |
Bytes: |
3 |
Flags: |
S=*,
Z=*, H=0, P/V=*, N=0, C=0 |
No
que toca ás
instruções lógicas chegamos ao fim.
Iremos mostrar ao longo do curso exemplos práticos do uso
destas instruções. |
Próxima
Lição - As
instruções de salto DJNZ, JR e JP. |
Anterior Indice Seguinte
|
|
P
U
B
L
I
C
I
D
A
D
E
|