1. Especificação do programa

O programa SUMREC01 processa um arquivo de clientes com registros de 80 bytes:

  • Lê cada registro do dataset SYSIN
  • Identifica o tipo pelo campo TIPO (posição 1, 1 byte): C=corporativo, P=pessoa física, X=cancelado
  • Conta registros por tipo e o total
  • Ao final, grava um relatório de sumário em SYSPRINT
  • Retorna RC=0 se OK, RC=8 se erro de I/O, RC=12 se dado inválido

2. Estrutura e layout de dados

Layout do registro de entrada (80 bytes): Posição 1 (1 byte) TIPO: C=corp, P=pf, X=cancel Posição 2-11 (10 bytes) CODCLI: código do cliente Posição 12-51 (40 bytes) NOMCLI: nome do cliente Posição 52-80 (29 bytes) RESTANTE: demais campos Layout da linha de relatório (133 bytes, FBA): Posição 1 (1 byte) ASA: controle de formulário Posição 2-132 (131 bytes) texto do relatório

3. Código completo anotado

* SUMREC01 — Sumarizador de registros de clientes SUMREC01 CSECT * ── PRÓLOGO ────────────────────────────────────────── STM R14,R12,12(R13) BALR R12,0 USING *,R12 ST R13,SAVAREA+4 LA R13,SAVAREA * ── INICIALIZAR CONTADORES ─────────────────────────── SR R2,R2 R2 = contador corporativos SR R3,R3 R3 = contador PF SR R4,R4 R4 = contador cancelados SR R5,R5 R5 = contador total * ── ABRIR ARQUIVOS ─────────────────────────────────── OPEN (ENTRADA,(INPUT),SAIDA,(OUTPUT)) TM ENTRADA+48,X'10' BZ ERROPEN * ── LOOP DE LEITURA ────────────────────────────────── RDLOOP GET ENTRADA,INREC A R5,=F'1' Total++ * Classificar por tipo CLI INREC,C'C' Corporativo? BE ECORP CLI INREC,C'P' Pessoa física? BE EPF CLI INREC,C'X' Cancelado? BE ECANC B EINVAL Tipo desconhecido ECORP A R2,=F'1' Corporativos++ B RDLOOP EPF A R3,=F'1' PF++ B RDLOOP ECANC A R4,=F'1' Cancelados++ B RDLOOP * Tipo inválido — gravar mensagem e setar RC=12 EINVAL MVC ERRMSG(10),INREC Copia início do registro WTO 'SUMREC01: TIPO INVALIDO ENCONTRADO' LA R15,12 ST R15,RCFINAL B RDLOOP * ── FIM DO ARQUIVO ─────────────────────────────────── FIMFILE BAL R10,RELATORIO Gerar relatório CLOSE (ENTRADA,,SAIDA) * ── EPÍLOGO ────────────────────────────────────────── L R13,SAVAREA+4 LM R14,R12,12(R13) L R15,RCFINAL Return Code BR R14 * ── SUBROTINA: GERAR RELATÓRIO ──────────────────────── RELATORIO DS 0H * Linha 1 — cabeçalho MVI OUTREC,C'1' ASA: nova página MVC OUTREC+1(30),=CL30'SUMREC01 - SUMARIO DE CLIENTES' PUT SAIDA,OUTREC * Linha 2 — corporativos (converter R2 para texto) MVI OUTREC,C' ' MVC OUTREC+1(132),OUTREC MVC OUTREC+1(15),=CL15'CORPORATIVOS: ' CVD R2,WORKDBL R2 → packed decimal em WORKDBL UNPK WORK8(8),WORKDBL+4(4) Unpacked → zona decimal OI WORK8+7,X'F0' Fix last digit sign MVC OUTREC+16(8),WORK8 PUT SAIDA,OUTREC * Linha 3 — PF (mesmo padrão) MVI OUTREC,C' ' MVC OUTREC+1(132),OUTREC MVC OUTREC+1(15),=CL15'PESSOA FISICA: ' CVD R3,WORKDBL UNPK WORK8(8),WORKDBL+4(4) OI WORK8+7,X'F0' MVC OUTREC+16(8),WORK8 PUT SAIDA,OUTREC * Linha 4 — total MVI OUTREC,C' ' MVC OUTREC+1(132),OUTREC MVC OUTREC+1(15),=CL15'TOTAL: ' CVD R5,WORKDBL UNPK WORK8(8),WORKDBL+4(4) OI WORK8+7,X'F0' MVC OUTREC+16(8),WORK8 PUT SAIDA,OUTREC BR R10 Retorna ao chamador (FIMFILE) * ── ERRO DE OPEN ───────────────────────────────────── ERROPEN WTO 'SUMREC01: ERRO AO ABRIR ARQUIVO' LA R15,8 B SAIRCOD SAIRCOD L R13,SAVAREA+4 LM R14,R12,12(R13) BR R14 * ── DCBs ───────────────────────────────────────────── ENTRADA DCB DSORG=PS,MACRF=(GM),DDNAME=SYSIN, RECFM=FB,LRECL=80,BLKSIZE=800, EODAD=FIMFILE SAIDA DCB DSORG=PS,MACRF=(PM),DDNAME=SYSPRINT, RECFM=FBA,LRECL=133,BLKSIZE=1330 * ── DADOS ──────────────────────────────────────────── SAVAREA DS 18F INREC DS CL80 OUTREC DS CL133 ERRMSG DS CL10 WORKDBL DS D Doubleword para CVD WORK8 DS CL8 Área de trabalho numérica RCFINAL DC F'0' Return Code inicial = 0 END SUMREC01

4. SNAP e diagnóstico de dumps

Quando um programa Assembler falha com ABEND, o z/OS pode gerar um dump — uma imagem da memória no momento do abend. A macro SNAP permite gerar um dump parcial em pontos específicos do código para debug:

Configuração para SNAP (precisa de DCB própria): SNAP DCB=SNAPDCB, Dataset onde o dump vai PDATA=(REGS), Inclui registradores ID=1 Identificador do snap SNAPDCB DCB DSORG=PS,MACRF=(W),DDNAME=SNAPDD, RECFM=VBA,LRECL=125,BLKSIZE=1632 No JCL: //SNAPDD DD SYSOUT=* Como ler um dump de Assembler: 1. PSW (Program Status Word) — mostra o endereço onde o abend ocorreu 2. Registradores no momento do abend (R0-R15) 3. Mapa de memória — identificar DCBs, buffers, savearea 4. Usar o listing do assembler para mapear endereço → instrução

O listing do assembler (PARM='OBJECT,NODECK,XREF(SHORT)' gera o listing no SYSPRINT) é essencial para debug: ele mostra o endereço de cada instrução, o endereço de cada label e a expansão de cada macro.

5. Dicas para código legado

SituaçãoO que verificar
ABEND S0C1 (operação inválida) Dado não-numérico em instrução aritmética; ponteiro inválido; branch para endereço errado
ABEND S0C4 (proteção de armazenamento) Acesso a área de memória sem autorização; R13 corrompido; savearea sobrescrita
ABEND S0C7 (exceção de dados) Campo packed decimal (P) com conteúdo inválido (não-numérico)
ABEND S322 (time exceeded) Loop infinito; espera por recurso; processamento maior que o esperado
ABEND S806 (módulo não encontrado) Nome de módulo errado; STEPLIB ou JOBLIB não inclui a biblioteca

💡 Preservação de registradores em código legado

Código Assembler antigo frequentemente usa registradores como R10, R11 para múltiplos fins ao longo do programa. Antes de modificar qualquer subrotina existente, mapeie quais registradores o código usa como base registers adicionais, quais são usados como ponteiros de dados e quais são usados como registradores de trabalho. Uma mudança inocente que altera R11 pode corromper o endereçamento de uma seção inteira do programa.

6. Próximos passos

Com a base desta trilha, você já consegue ler e modificar programas Assembler legados. Os tópicos avançados para continuar:

TópicoPara que serve
AMODE/RMODE (31-bit / 64-bit)Programas que acessam memória acima de 16MB / 2GB
SVCs e macros de sistemaChamadas diretas ao z/OS — DYNALLOC, ENQ/DEQ, STORAGE
Programas reentrantesCódigo que pode ser executado simultaneamente por múltiplos usuários
Assembler em CICSComandos EXEC CICS em módulos Assembler
Instruções SIMD (z14+)Operações vetoriais para processamento em massa de dados