1. Os 16 registradores de propósito geral

O z/Architecture tem 16 registradores de propósito geral (GPR — General Purpose Registers), numerados de R0 a R15. Cada um tem 64 bits (8 bytes), mas pode ser usado em modo de 32 bits (baixos 32 bits) em operações clássicas.

🦕 Analogia — registradores como bancada de trabalho

Imagine uma bancada com 16 gavetas. A memória principal é o depósito — tem muita capacidade, mas você precisa trazer o item para a bancada (registrador) antes de trabalhar. Todas as operações Assembler acontecem nas gavetas. Você carrega da memória para a gaveta, opera, e guarda de volta na memória.

2. Convenções de uso dos registradores

Embora qualquer registrador possa ser usado para qualquer fim, existe uma convenção de uso forte no z/OS que todo programa deve respeitar — especialmente ao chamar e ser chamado por outros programas:

RegistradorUso convencionalDeve ser preservado?
R0Parâmetro / resultado / não preservadoNão
R1Ponteiro para lista de parâmetrosNão
R2–R11Uso geral — trabalho e variáveis locaisSim (se alterado)
R12Base register (endereçamento de código)Sim
R13Ponteiro para a savearea (área de salvamento)Sim
R14Endereço de retorno ao chamadorNão precisa preservar (caller salva)
R15Endereço do programa chamado / Return CodeNão precisa preservar

A savearea (área de salvamento) é uma estrutura de 18 fullwords (72 bytes em 32-bit / 144 bytes em 64-bit) onde o programa salva os registradores do chamador. Isso permite que, ao retornar, o chamador encontre seus registradores intactos.

Savearea padrão (modo 31-bit / 32-bit): Offset 0: Palavra reservada (R14 do chamador do chamador) Offset 4: Ponteiro para savearea anterior (R13 do chamador) Offset 8: Ponteiro para savearea do chamado (R13 do chamado) Offset 12: R14 salvo (endereço de retorno) Offset 16: R15 salvo Offset 20: R0 salvo ... ... Offset 72: R12 salvo Declaração no código: SAVAREA DS 18F 18 fullwords = 72 bytes

3. Base register e endereçamento

O Assembler z/Architecture usa endereçamento relativo ao base register. Toda instrução que referencia memória usa a forma deslocamento(base) ou deslocamento(índice,base).

Isso significa que o código do programa não usa endereços absolutos — usa deslocamentos a partir de um registrador base. Isso permite que o programa seja carregado em qualquer endereço de memória e funcione corretamente.

Endereçamento com base register: L R2,100(R12) Carrega palavra em R12+100 MVC 0(8,R3),0(R4) Move 8 bytes: de R4+0 para R3+0 LA R5,DADOS(R12) Carrega endereço de DADOS (R12 + deslocamento) Um label como "DADOS" vira um deslocamento relativo ao base register: DADOS DC CL8'EXEMPLO' Se DADOS está 200 bytes após onde R12 aponta: → LA R5,DADOS é montado como LA R5,200(R12)

4. BALR e USING — o par fundamental

O BALR (Branch And Link Register) carrega o endereço da próxima instrução em um registrador. O USING informa ao assembler qual registrador usar como base e a partir de qual endereço.

BALR R12,0 R12 ← endereço da instrução seguinte USING *,R12 A partir daqui, R12 é base de endereçamento Expansão do que acontece: Antes de BALR: PC aponta para a instrução BALR BALR R12,0: R12 ← PC da próxima instrução (pós-BALR) o segundo operando R0 = não desvia (fica na próxima instrução) USING *,R12: assembler sabe que R12 aponta para '*' (aqui) e usa R12 para calcular deslocamentos de labels

O USING é uma diretiva de montagem — não gera código. Ele instrui o assembler a calcular os deslocamentos dos labels usando R12 como base. Sem o USING, o assembler não sabe qual registrador usar e dá erro.

💡 Limite de 4096 bytes por base register

Um base register só endereça 4096 bytes (12 bits de deslocamento) a partir do seu valor. Programas maiores que 4096 bytes precisam de múltiplos base registers. A instrução USING *,R12,R11 define dois base registers, e o assembler automaticamente usa o correto para cada label.

5. Modelo de memória e tipos de dado

A memória do z/OS é endereçada em bytes. Os tipos de dado em Assembler são declarados com as diretivas DC (Define Constant) e DS (Define Storage):

TipoSignificadoExemploTamanho
CCharacter (EBCDIC)DC CL8'NOME '1 byte por char
FFullword (inteiro 32-bit)DC F'12345'4 bytes
HHalfword (inteiro 16-bit)DC H'100'2 bytes
GDoubleword (inteiro 64-bit)DC G'99999'8 bytes
PPacked decimalDC P'12345'variável
ZZoned decimalDC Z'12345'1 byte por dígito
XHexadecimalDC X'FF00'1 byte por 2 hex
AAddress (ponteiro 32-bit)DC A(DADOS)4 bytes
Exemplos de DC e DS: NOME DC CL20'MARIA DA SILVA ' Constante EBCDIC 20 bytes VALOR DC F'0' Fullword inicializado em 0 BUFFER DS CL80 80 bytes sem valor inicial WORK DS F 1 fullword sem valor inicial TABLE DS 10F 10 fullwords (40 bytes) PTR DC A(NOME) Endereço de NOME (4 bytes) FLAGS DC X'00' 1 byte hex = 0x00

A diferença entre DC e DS: DC inicializa a memória com um valor; DS apenas reserva o espaço sem inicializar.