Conjunto de Instruções e Modos de Endereçamento

Nesse exemplo, a diretiva ORG <número> determina a posição da memória em que a próxima instrução será colocada na memória de programa. Já a diretiva END indica o fim do programa.

ORG 00h ; endereço inicial do programa
MOV A, #1 ; move valor 1 para Acumulador
LOOP:
MOV P1, A ; move conteúdo do Acumulador para P1
SETB P1.4 ; faz P1.4 = 1 (pull-up interno) - pino de entrada
JNB P1.4, CH_PR ; testa se P1.4 é igual a zero. Se sim, vai para CH_PR
RR A ; se não, rotaciona os bits do Acumulador para direita
SJMP LOOP ; pula para LOOP
CH_PR:
RL A ; rotaciona os bits do Acumulador para esquerda
SJMP LOOP ; pula para LOOP
END

Modos de Endereçamento

  • Direto:

    • O endereço do operando é determinado pela própria instrução (endereço de 8 bits).

    • Neste caso, apenas a RAM interna e os registradores especiais podem ser acessados.

  • Indireto:

    • O endereço do operando é determinado por um registrador.

    • Um endereço de 8 bits pode ser determinado pelos registradores R0~R1 do banco de registradores atual, ou pelo Stack Pointer.

    • Endereços de 16 bits só podem ser especificados pelo registrador DPTR.

  • Imediato:

    • O operando é a constante.

  • Registrador:

    • Os registradores R0~R7 do banco atual são acessados pela instrução.

  • Registrador Específico:

    • A operação da instrução é realizada em um registrador específico.

    • Neste caso, não é necessário indicar um endereço.

  • Indexado:

    • Somente a memória de programa pode ser acessada.

    • Apenas operações de leitura são possíveis.

    • Utilizado em instruções de salto e look-up table.

No último modo, os registradores PC e DPTR podem ser usados para armazenar um endereço base. Já o acumulador é utilizado para determinar o offset.

Símbolos utilizados:

  • C: Flag de carry;

  • A: Acumulador;

  • PC: Contador de Programa;

  • DPTR: Ponteiro;

  • N: Endereço de 8 bits;

  • NN: Endereço de 16 bits;

  • #N: Constante de 8 bits;

  • Rn: Registrador Rn (R0~R7) do banco atual de registradores;

  • @Ri: Endereço é determinado pelo registrador Ri (R0 ou R1);

  • H: indica que o valor está na base hexadecimal;

  • B: indica que o valor está na base binária;

Instruções de Movimentação de Dados

Instruções de Movimentação de Dados

Instruções de Movimentação de Dados

Instruções de Movimentação de Dados

De modo geral, quando o destino é o acumulador:

MOV

A,Rn

Move o registro Rn para o Acumulador

MOV

A,N

Move o conteúdo da memória N para o Acumulador

MOV

A,@Ri

Move o conteúdo da RAM endereçada por Ri para o Acumulador

MOV

A,#N

Move a constante N para o Acumulador

MOVC

A,@A+DPTR

Soma A + DPTR obtendo um endereço de 16 bits na memória de programa. Carrega o acumulador com o conteúdo desta memória

MOVC

A,@A+PC

Idem ao anterior, mas soma A + PC

MOVX

A,@Ri

Move o conteúdo da RAM endereçada por Ri para o Acumulador

MOVX

A,@DPTR

Move RAM externa endereçada por DPTR (endereço 16 bits) para o Acumulador

XCH

A,Rn

Troca entre si o conteúdo do Acumulador e do Registro Rn

XCH

A,N

Troca entre si o conteúdo da memória N com Acumulador

XCH

A,@Ri

Troca entre si a RAM endereçada por Ri com Acumulador

XCHD

A,@Ri

Troca entre si o nibble menos significativo do Acumulador e da RAM endereçada por Ri

Quando o destino é um registrador:

MOV

Rn,A

Move o Acumulador para o registro Rn

MOV

Rn,N

Move o conteúdo da memória N para o registro Rn

MOV

Rn,#N

Move a constante N para o registro Rn

MOV

DPTR,#NN

Move constante NN para o DPTR

Quando o destino é um endereço direto:

MOV

N,A

Move o Acumulador para a memória N

MOV

N,Rn

Move o registro Rn para a memória N

MOV

N1,N2

Move o conteúdo da memória N2 para a memória N1

MOV

N,@Ri

Move RAM endereçada por Ri para a memória N

MOV

N,#N

Move a constante N para o conteúdo da memória N

PUSH

N

Incrementa o SP e então coloca a memória no Stack

POP

N

Retira dado do Stack e coloca na memória, depois decrementa SP

Quando o destino é um endereço indireto:

MOV

@Ri,A

Move o Acumulador para a RAM endereçada por Ri

MOV

@Ri,N

Move o conteúdo da memória N para a RAM endereçada por Ri

MOV

@Ri,#N

Move a constante N para a RAM endereçada por Ri

MOVX

@DPTR,A

Move Acumulador para a RAM externa endereçada por DPTR (endereço 16 bits)

Instruções Aritméticas

Instruções aritméticas [1].

Quando o destino é o acumulador:

ADD

A,Rn

Soma Rn ao Acumulador

ADD

A,N

Soma o conteúdo da posição de memória N ao Acumulador

ADD

A,@Ri

Soma o conteúdo da RAM endereçada por Ri ao Acumulador

ADD

A,#N

Soma a constante N ao Acumulador

ADDC

A,Rn

Soma Rn e o flag Carrry ao Acumulador

ADDC

A,N

Soma o conteúdo da posição de memória N e o flag Carry ao Acumulador

ADDC

A,@Ri

Soma o conteúdo da RAM endereçada por Ri e o flag Carry ao Acumulador

ADDC

A,#N

Soma a constante N e flag Carry ao Acumulador

SUBB

A,Rn

Subtrai Rn e o flag Carry do Acumulador

SUBB

A,N

Subtrai o conteúdo da posição de memória N e o flag Carry do Acumulador

SUBB

A,@Ri

Subtrai o conteúdo da RAM endereçada por Ri e o flag Carry do Acumulador

SUBB

A,#N

Subtrai a constante N e o flag Carry do Acumulador

INC

A

Soma 1 ao Acumulador

DEC

A

Subtrai 1 do Acumulador

DA

A

Ajuste decimal do Acumulador

DIV

AB

Divide A e B, resultado: A inteiro e B resto

MUL

AB

Multiplica A e B, resultado: BA

Cabe ressaltar que nas operações de adição, subtração e incremento o flag de carry e de overflow são alterados. As operações de multiplicação e divisão zeram o flag de carry, e no caso da multiplicação, a flag de overflow é modificada. Além disso, a instrução de ajuste decimal também modifica a flag de carry.

Quando o destino é um registrador:

INC

Rn

Soma 1 ao Rn

DEC

Rn

Subtrai 1 de Rn

Instruções Lógicas

Instruções Lógicas [1].

Quando o destino é o acumulador:

ANL

A, Rn

Operação “E” entre Rn e Acumulador

ANL

A,N

Operação “E” entre o conteúdo da memória N e o Acumulador

ANL

A,@Ri

Operação “E” entre RAM endereçada por Ri e Acumulador

ANL

A,#N

Operação “E” entre a constante N e Acumulador

ORL

A,Rn

Operação “OU” entre Rn e Acumulador

ORL

A,N

Operação “OU” entre memória N e Acumulador

ORL

A,@Ri

Operação “OU” entre RAM endereçada por Ri e Acumulador

ORL

A,#N

Operação “OU” entre constante N e Acumulador

XRL

A,Rn

Operação “OU EXCLUSIVO” entre Rn e Acumulador

XRL

A,N

Operação “OU EXCLUSIVO” entre o conteúdo da memória N e Acumulador

XRL

A,@Ri

Operação “OU EXCLUSIVO” entre RAM endereçada por Ri e Acumulador

XRL

A,#N

Operação “OU EXCLUSIVO” entre constante N e Acumulador

Quando o destino é um endereço direto:

ANL

N,A

Operação “E” entre Acumulador e memória N

ANL

N,#N

Operação “E” entre constante N e memória N

ORL

N,A

Operação “OU” entre Acumulador e conteúdo da memória N

ORL

N,#N

Operação “OU” entre constante N e conteúdo da memória N

XRL

N,A

Operação “OU EXCLUSIVO” entre Acumulador e conteúdo da memória N

XRL

N,#N

Operação “OU EXCLUSIVO” entre a constante N e o conteúdo da memória N

Operação sobre o acumulador:

RL

A

Faz A = 0

CPL

A

Inverte o estado dos bits do Acumulador

SWAP

A

Troca os nibbles do Acumulador

RL

A

Rotação do Acumulador para esquerda

RLC

A

Rotação do Acumulador para esquerda através do flag Carry

RR

A

Rotação do Acumulador para direita

RRC

A

Rotação do Acumulador para direita através do flag Carry

Instruções Booleanas e de Desvio

Instruções Booleanas e de Desvio

Operações utilizando o endereçamento de bits:

LR

bit

Zera o bit endereçado

SETB

bit

Seta o bit endereçado

CPL

bit

Inverte o estado do bit endereçado

MOV

bit,C

Move o flag Carry para o bit endereçado

JB

bit,N

Desvia se o bit endereçado estiver setado

JNB

bit,N

Desvia se o bit endereçado estiver zerado

JBC

bit,N

Desvia se o bit endereçado estiver setado e depois zera o bit

Operações sobre o flag de Carry:

CLR

C

Zera o flag Carry

SETB

C

Seta o flag Carry

CPL

C

Inverte o estado do flag Carry

MOV

C,bit

Move o bit endereçado para o flag Carry

ANL

C,bit

Operação “E” entre o bit endereçado e o flag Carry

ANL

C,/bit

Operação “E” entre o complemento do bit endereçado e o flag Carry

ORL

C,bit

Operação “OU” entre o bit endereçado e o flag Carry

ORL

C,/bit

Operação “OU” entre o complemento do bit endereçado e o flag Carry

JC

N

Desvia se o flag Carry estiver setado

JNC

N

Desvia se o flag Carry estiver zerado

Instruções de Salto

Instruções de salto incondicional são bastante simples. Basicamente, um endereço alvo é utilizado para alterar o fluxo de execução, isto é, o contador de programa. Na figura são mostradas as instruções capazes de alterar o fluxo de execução do programa, com exceção da instrução NOP, que não realiza nenhuma operação.

Instruções de Salto [1].

As instruções JMP e CALL possuem as seguintes variações:

ACALL

N

Chama sub-rotina numa faixa de 2 Kbytes da atual posição

LCALL

NN

Chama sub-rotina em qualquer posição da memória de programa

AJMP

N

Desvia para outro endereço numa faixa de 2 Kbytes da atual posição.

LJMP

NN

Desvia para qualquer posição da memória

SJMP

N

Desvio curto relativo

Outras duas instruções que alteram o valor do contador de programa são as de retorno de sub-rotina e retorno de interrupção.

RET

Retorna da sub-rotina

RETI

Retorna da interrupção

O desvio também pode ser tomado com base no resultado de uma comparação. Nesse caso, o desvio é dito condicional.

Desvio condicional [1].

CJNE

A,N,N

Compara e desvia se o Acumulador for diferente do conteúdo da memória N

CJNE

A,#N,N

Compara e desvia se o Acumulador for diferente da constante N

CJNE

Rn,#N,N

Compara e desvia se o Rn for diferente da constante N

CJNE

@Ri,#N,N

Compara e desvia se a RAM endereçada por Ri for diferente da constante N

DJNZ

N,N

Decrementa o conteúdo da memória N e desvia se for diferente de “zero”

DJNZ

Rn, N

Decrementa Rn e desvia se for diferente de “zero”

JZ

N

Desvia se o Acumulador for “zero”

JNZ

N

Desvia se o Acumulador “não for zero”

Cabe ressaltar que as instruções CJNE modificam a flag de carry.

  • Exemplo de acesso a memória externa: Zera os elementos de um vetor que são iguais a FFH.

ORG 00h ; endereço inicial do programa
MOV DPTR, #500h ; move valor 500h para DPTR
MOV R0, #50 ; move valor 50 para R0
LOOP:
MOVX A, @DPTR ; move conteúdo apontado por DPTR para Acumulador
CJNE A, #0FFH, DIFER ; compara conteúdo do Acumulador com 0FFH. Se for diferente, vai para DIFER
MOV A, #0 ; caso contrário, move valor 0 para Acumulador
MOVX @DPTR, A ; move conteúdo do Acumulador para endereço apontado por DPTR
DIFER:
INC DPTR ; incrementa DPTR
DJNZ R0, LOOP ; decrementa R0 e compara com 0. Se for diferente, vai para LOOP
SJMP $ ; espera (LOOP)
END
  • Exemplo de acesso a memória externa: Copia os dados de um vetor para outro.

ORG 00h ; endereço inicial do programa
MOV R0, #0 ; move valor 0 para R0 (endereço de origem)
MOV R1, #50 ; move valor 50 para R1 (número de elementos)
MOV DPTR, #50h ; move valor 50H para DPTR (endereço de destino)
LOOP:
MOVX A, @R0 ; move para Acumulador o conteúdo do endereço apontado por R0
MOVX @DPTR, A ; move conteúdo do Acumulador para endereço apontado por DPTR
INC R0 ; incrementa R0 (endereço de origem)
INC DPTR ; incrementa DPTR (endereço de destino)
DJNZ R1, LOOP ; decrementa R1. Se for diferente de zero, vai para LOOP
SJMP $ ; espera
END