1. Load e Store — movendo dados

Em Assembler, você não opera diretamente na memória — você carrega em registrador, opera e armazena de volta. As instruções principais:

InstruçãoAçãoExemplo
L Rx,D(Rb)Load fullword da memória para registradorL R2,VALOR
LH Rx,D(Rb)Load halfword com extensão de sinalLH R2,HALF
LR Rx,RyLoad registrador (copia Ry em Rx)LR R4,R2
LA Rx,D(Rb)Load Address — carrega o endereço (não o valor)LA R3,BUFFER
ST Rx,D(Rb)Store fullword do registrador para memóriaST R2,RESULT
STH Rx,D(Rb)Store halfwordSTH R2,HALF
STC Rx,D(Rb)Store Character (1 byte)STC R2,BYTE
Exemplos de Load e Store: L R2,VALOR R2 ← conteúdo de VALOR (4 bytes) LR R3,R2 R3 ← R2 (cópia de registrador) LA R4,BUFFER R4 ← endereço de BUFFER (não o conteúdo) ST R3,RESULT RESULT ← R3 (4 bytes) LA com deslocamento — muito usado para avançar ponteiros: LA R4,80(R4) R4 ← R4 + 80 (avança 1 linha de 80 bytes) LA R4,0(R4,R5) R4 ← R4 + R5 (soma dois registradores) Dados referenciados: VALOR DC F'42' RESULT DS F BUFFER DS CL80

💡 LA não acessa memória

LA R4,BUFFER carrega o endereço de BUFFER em R4 — não o conteúdo. É equivalente ao operador & do C. Já L R4,BUFFER carrega os 4 bytes que estão no endereço BUFFER. Confundir os dois é um dos erros mais comuns de iniciantes.

2. MVC e MVI — movendo caracteres

Para mover strings (campos de caracteres), o Assembler usa instruções SS (Storage-to-Storage):

InstruçãoAção
MVC D1(L,B1),D2(B2)Move L bytes de B2+D2 para B1+D1 (L=1 a 256)
MVI D1(B1),imm8Move um byte imediato para B1+D1
MVCL Rx,RyMove até 16MB — comprimento em par de registradores
MVC — move até 256 bytes de uma vez: MVC DESTINO(20),ORIGEM Move 20 bytes de ORIGEM para DESTINO MVC 0(80,R3),0(R4) Move 80 bytes: de R4+0 para R3+0 MVI — inicializa um byte com valor imediato: MVI FLAG,X'01' FLAG ← 0x01 MVI 0(R3),C' ' Byte em R3 ← espaço EBCDIC Truque: inicializar um buffer com espaços: MVI BUFFER,C' ' Primeiro byte ← espaço MVC BUFFER+1(79),BUFFER Propaga: copia byte 0 para bytes 1-79 (funciona porque MVC copia da esquerda para direita, byte a byte)

3. Aritmética inteira

Aritmética com fullwords (32-bit). As operações são sempre no registrador:

InstruçãoAção
A Rx,D(Rb)Add — Rx ← Rx + memória
AR Rx,RyAdd Register — Rx ← Rx + Ry
S Rx,D(Rb)Subtract — Rx ← Rx - memória
SR Rx,RySubtract Register — Rx ← Rx - Ry
M Rx,D(Rb)Multiply — par Rx:Rx+1 ← Rx+1 * memória
MR Rx,RyMultiply Register — par Rx:Rx+1 ← Rx+1 * Ry
D Rx,D(Rb)Divide — quociente em Rx+1, resto em Rx
DR Rx,RyDivide Register — quociente em Rx+1, resto em Rx
Exemplos de aritmética: L R2,VALORA R2 ← VALORA A R2,VALORB R2 ← R2 + VALORB (soma) S R2,VALORC R2 ← R2 - VALORC (subtração) ST R2,RESULT grava resultado Multiplicação — atenção ao par de registradores: L R3,FATOR1 R3 ← FATOR1 M R2,FATOR2 par R2:R3 ← R3 * FATOR2 R2 recebe os bits altos (geralmente 0), R3 o resultado ST R3,PRODUTO grava produto Divisão: SR R2,R2 zera R2 (parte alta do dividendo) L R3,DIVIDENDO D R2,DIVISOR R2 ← resto, R3 ← quociente ST R3,QUOCIENTE ST R2,RESTO

4. Comparação e Condition Code

Toda instrução de comparação seta o Condition Code (CC) — um campo de 2 bits no PSW (Program Status Word) com 4 valores possíveis:

CCSignificado (comparação)Significado (aritmética)
0IgualResultado = 0
1Primeiro operando menorResultado < 0
2Primeiro operando maiorResultado > 0
3(não usado)Overflow
InstruçãoCompara
C Rx,D(Rb)Registrador com fullword na memória (com sinal)
CR Rx,RyRegistrador com registrador (com sinal)
CL Rx,D(Rb)Registrador com fullword (sem sinal — logical)
CLC D1(L,B1),D2(B2)Bytes na memória com bytes na memória (até 256 bytes)
CLI D1(B1),imm8Byte na memória com valor imediato
Exemplos de comparação: C R2,LIMITE Compara R2 com LIMITE (inteiro) CLC NOME(20),PADRAO Compara 20 bytes de NOME com PADRAO CLI FLAG,X'01' Compara 1 byte de FLAG com 0x01

5. Desvio condicional — B e BC

O desvio (branch) testa o Condition Code e salta para um label se a condição for verdadeira. A instrução base é BC mask,label:

MnemônicoMáscaraDesvia quando
B15Sempre (desvio incondicional)
BE8Equal (CC=0)
BNE7Not Equal (CC≠0)
BL4Low / Less than (CC=1)
BH2High / Greater than (CC=2)
BNH13Not High (CC=0 ou CC=1)
BNL11Not Low (CC=0 ou CC=2)
BZ8Zero (CC=0) — alias de BE
BNZ7Not Zero (CC≠0) — alias de BNE
BO1Overflow (CC=3)

6. Exemplo completo — lógica IF/ELSE

Um trecho que implementa: "Se VALOR > 100, gravar ALTO; senão gravar BAIXO":

* IF VALOR > 100 THEN RESULT = 'ALTO' ELSE RESULT = 'BAIXO' L R2,VALOR Carrega VALOR em R2 C R2,=F'100' Compara com 100 (literal fullword) BNH EBAIXO Se R2 <= 100, vai para EBAIXO EALTO MVC RESULT(4),=CL4'ALTO' RESULT ← 'ALTO' B EFIM Salta o else EBAIXO MVC RESULT(5),=CL5'BAIXO' RESULT ← 'BAIXO' EFIM DS 0H Label de continuação (DS 0H = sem dado) VALOR DC F'150' RESULT DS CL5

Note o uso de literais (=F'100', =CL4'ALTO') — o assembler aloca automaticamente o dado na seção de literais do programa, economizando uma declaração DC explícita.

Loop — contar de 1 a 10: LA R2,1 R2 ← 1 (contador) LA R3,10 R3 ← 10 (limite) LOOP CR R2,R3 Compara contador com limite BH ENDLOOP Se R2 > R3, sai do loop * Corpo do loop — processar R2 A R2,=F'1' R2 ← R2 + 1 B LOOP Volta ao início ENDLOOP DS 0H