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

De modo geral, quando o destino é o acumulador:

Quando o destino é um registrador:

Quando o destino é um endereço direto:

Quando o destino é um endereço indireto:

Instruções Aritméticas

Quando o destino é o acumulador:

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:

Instruções Lógicas

Quando o destino é o acumulador:

Quando o destino é um endereço direto:

Operação sobre o acumulador:

Instruções Booleanas e de Desvio

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

Operações sobre o flag de Carry:

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.

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

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.

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

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

Last updated