Translate

Mostrar mensagens com a etiqueta call. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta call. Mostrar todas as mensagens

quarta-feira, 28 de fevereiro de 2024

Programas COBOL Aninhados: Os Holocrons Secretos Escondidos Dentro de um Único Load Module

 

Bellacosa Mainframe e o caso do programa COBOL com varios pgms aninhados

Programas COBOL Aninhados: Os Holocrons Secretos Escondidos Dentro de um Único Load Module

Quando o Padawan Descobre que um Programa COBOL Pode Conter Outros Programas COBOL em Seu Interior

Por Bellacosa Mainframe

"Nem todo programa precisa viver sozinho. Alguns mestres escondem seus aprendizes dentro do próprio templo."

Mestre Bellacosa Sysprog Jedi

Durante décadas, boa parte dos desenvolvedores COBOL aprendeu uma arquitetura bastante simples:

Programa A

CALL Programa B

CALL Programa C

GOBACK

Fim.

Era o modelo clássico.

Cada programa em um membro.

Cada módulo separado.

Cada compilação independente.

Cada load module vivendo sua própria vida no PDS ou PDSE.

Mas então o jovem Padawan encontra algo estranho em um código legado:

IDENTIFICATION DIVISION.
PROGRAM-ID. CLIENTES.

...

IDENTIFICATION DIVISION.
PROGRAM-ID. VALIDA-CPF.

...

IDENTIFICATION DIVISION.
PROGRAM-ID. CALCULA-IDADE.

Ele arregala os olhos.

Pensa:

Mestre...

Tem três programas no mesmo fonte...

Isso é magia negra?

Não.

É COBOL.

E existe há muito tempo.

Poucos desenvolvedores modernos utilizam essa funcionalidade.

Menos ainda entendem completamente como ela funciona.

E alguns veteranos passam a carreira inteira sem escrever um único programa aninhado.

Hoje vamos abrir esse antigo holocron.


O que é um Programa Aninhado?

Em COBOL, um programa pode conter outros programas.

Algo semelhante a:

Programa principal

  • Programa filho A

  • Programa filho B

  • Programa filho C

Tudo dentro do mesmo fonte.

Exemplo:

PROGRAMA PRINCIPAL


PROGRAMA FILHO


PROGRAMA NETO

Hierarquia.

Muito parecido com:

Java

Inner Class

Python

Nested Function

Pascal

Nested Procedures

COBOL possui conceito semelhante.


Quando Surgiu?

Programas aninhados apareceram nas especificações modernas do COBOL.

Principalmente:

COBOL 85

Posteriormente aprimorados em:

Enterprise COBOL V3

V4

V5

V6

Hoje são totalmente suportados.

COBOL 6.5

IBM z16

IBM z17


Estrutura Básica

Exemplo.

Programa Principal

IDENTIFICATION DIVISION.
PROGRAM-ID. CLIENTE.

Programa interno

IDENTIFICATION DIVISION.
PROGRAM-ID. VALIDA.

Outro

IDENTIFICATION DIVISION.
PROGRAM-ID. CALCULA.

Tudo junto.


Exemplo Completo

Programa Pai

IDENTIFICATION DIVISION.
PROGRAM-ID. CLIENTE.


DATA DIVISION.


WORKING-STORAGE SECTION.


01 WS-CPF.
PIC X(11).



PROCEDURE DIVISION.


MOVE '12345678901'
TO WS-CPF


CALL 'VALIDA'


DISPLAY "FIM"



STOP RUN.

Programa Filho

IDENTIFICATION DIVISION.
PROGRAM-ID. VALIDA.


PROCEDURE DIVISION.


DISPLAY 'VALIDANDO'


EXIT PROGRAM.

Fim.


Exemplo Realista

Vamos construir.

Sistema cadastro.

Programa principal

CADASTRO

Filhos

VALIDA-CPF

VALIDA-DATA

CALCULA-IDADE

GERA-LOG


Passo 1

Programa principal

PROGRAM-ID. CADASTRO.

Passo 2

WS

01 WS-CPF.
01 WS-DATA.
01 WS-IDADE.

Passo 3

Chamar programas internos

CALL 'VALIDA-CPF'

CALL 'VALIDA-DATA'

CALL 'CALCULA-IDADE'

Passo 4

Definir programa interno

IDENTIFICATION DIVISION.
PROGRAM-ID. VALIDA-CPF.

Passo 5

Lógica

IF CPF NUMERIC

DISPLAY 'OK'

ELSE

DISPLAY 'ERRO'

Passo 6

Encerrar

EXIT PROGRAM.

Passo 7

Novo programa

PROGRAM-ID. CALCULA-IDADE.

Tudo dentro do mesmo fonte.


Como COBOL Enxerga Isso?

COBOL vê:

Programa Pai

Programa Filho

Programa Neto

Estrutura hierárquica.


Como é Chamado?

Nested Program

Programa Interno

Contained Program

Outer Program

Inner Program


Como Funciona na Memória?

Aqui a magia começa.

Suponha:

CADASTRO

contém

VALIDA

contém

LOG


Carregamento

LOAD MODULE


CADASTRO


VALIDA


LOG

Tudo junto.

Mesmo módulo.


Não existe:

Busca catálogo

Load library

Fetch

Link

Já está residente.


Vantagem

Muito rápida.


Visualmente

Programa separado

CALL


LOAD


FETCH


EXECUTA

Programa interno

CALL


EXECUTA

Menos overhead.


Compartilhamento de Variáveis

Esse é o recurso mais poderoso.

Programa interno pode acessar dados externos.

Exemplo

Programa pai

01 WS-NOME.
PIC X(30).

Filho

DISPLAY WS-NOME.

Sem USING.

Sem linkage.

Sem parâmetro.

Sem copiar.


Mágica?

Não.

Escopo léxico.


Exemplo

Pai

MOVE 'BELLACOSA'

TO WS-NOME

Filho

DISPLAY WS-NOME

Resultado

BELLACOSA

Por Que Isso Existe?

Reduzir acoplamento.

Criar rotinas privadas.

Encapsulamento.

Organização.


É semelhante a:

Método privado Java

Função interna Python

Classe interna


Curiosidade

Muitos programadores COBOL nem sabem que isso existe.

Porque nos bancos normalmente vemos:

CALL externo

PDS

Loadlib

Arquitetura tradicional.


Exemplo de Encapsulamento

Programa externo

Atendimento.

Internos

Valida

Log

Criptografa

Audita

Ninguém pode chamar diretamente.


Somente programa pai.


Segurança

Excelente vantagem.

Programa externo:

QUALQUER UM CHAMA

Interno

SÓ O PAI CHAMA

Maior controle.


Performance

Muito boa.

Programa já está carregado.

Sem I/O.

Sem busca.

Sem FETCH.


Pode economizar milhares de chamadas.


Existe Desvantagem?

Sim.

Grande.


Fonte gigantesco.

50000 linhas.

100000 linhas.

Difícil manutenção.


Problema do Monstro Cósmico

Exemplo

CADASTRO


VALIDA


IDADE


LOG


EMAIL


TOKEN


PIX


SMS


AUDITORIA


JSON


XML


MQ


DB2

Tudo junto.

Virou um kaiju.


Dificuldade de Reuso

Programa interno não pode ser facilmente reutilizado.

Outro sistema quer usar.

Não consegue.


Terá que copiar.

Ou refatorar.


Debug

Pode confundir.

Call stack enorme.

Nested levels.


IBM Debug Tool ajuda.

Fault Analyzer também.


Cuidados

1 Não exagerar

Máximo recomendado:

3 níveis

Pai

Filho

Neto

Mais que isso:

Dor.


2 Documentar

Quem chama quem.


3 Evitar dependência excessiva

Filho acessando 500 WS.

Ruim.


4 Preferir USING

Mesmo podendo acessar WS externa.

Melhor:

USING WS-CPF

Mais claro.


5 Não esconder regras críticas

Exemplo

Cálculo juros.

Pode dificultar auditoria.


Como Compilar?

Normal.

IGYCRCTL

Enterprise COBOL

Sem segredo.


Compilador entende estrutura.

Gera módulo único.


Programa Recursivo Aninhado

Sim.

É possível.

Filho pode ser:

RECURSIVE


Exemplo

PROGRAM-ID. FATORIAL.


RECURSIVE.

Dentro do pai.


Muito elegante.

Pouco usado.


CALL Estático Interno

Muito eficiente.

CALL 'VALIDA-CPF'

Sem carga.

Sem fetch.


Comparação

CaracterísticaPrograma ExternoPrograma Interno
ReusoExcelenteBaixo
SegurançaMédiaAlta
PerformanceBoaExcelente
EncapsulamentoMédioExcelente
DebugFácilMédio
OrganizaçãoBoaBoa
ManutençãoExcelentePode degradar
DistribuiçãoFácilLimitada

Quando Vale a Pena?

Eu costumo ensinar aos Padawans uma regra simples.

Use programas aninhados quando a rotina fizer sentido apenas dentro daquele programa principal.

Exemplos:

✅ Validação interna

✅ Máscara

✅ Auditoria

✅ Log

✅ Conversão local

✅ Parser pequeno


Evite para:

❌ Acesso DB2

❌ MQ

❌ APIs

❌ Serviços compartilhados

❌ Criptografia corporativa

❌ Regras usadas por dezenas de sistemas


O Conselho Final do Mestre Bellacosa

Programas aninhados em COBOL são quase como compartimentos secretos escondidos em um gigantesco cruzador estelar IBM Z. Eles oferecem encapsulamento, velocidade, organização e um nível de proteção natural contra reutilização indevida.

Mas, assim como qualquer artefato poderoso do universo dos Sysprogs Jedi, devem ser usados com sabedoria.

Um pequeno programa interno de validação pode tornar um sistema elegante e fácil de entender.

Dez programas internos profundamente dependentes das variáveis do pai podem transformar um módulo em um labirinto digno de um antigo datacenter abandonado, onde cada alteração provoca medo, regressões e longas noites analisando dumps.

A filosofia Bellacosa Mainframe é simples:

Aninhe comportamentos, não sistemas inteiros.

Encapsule segredos, não complexidade desnecessária.

E lembre-se sempre: se o Padawan precisar de três cafés, dois dumps e um Fault Analyzer para entender a estrutura do programa, talvez o lado sombrio da manutenção já tenha vencido.


 

quinta-feira, 3 de janeiro de 2019

☕💥 A Jornada do Padawan COBOL – Parte 1 Desvendando o Universo dos CALLs no Mainframe

 

Bellacosa Mainframe e o CALL em programas COBOL Parte I

☕💥 A Jornada do Padawan COBOL – Parte 1

Desvendando o Universo dos CALLs no Mainframe

Ou como descobrir que chamar um programa em COBOL é quase tão importante quanto saber preparar café às 3 da manhã durante uma janela de produção

Por Vagner Bellacosa – Bellacosa Mainframe


Introdução

Todo desenvolvedor COBOL passa por um momento de iluminação.

Normalmente acontece quando ele abre um programa de produção com 30 mil linhas e encontra algo parecido com isto:

CALL 'PROG0001'
USING WS-AREA.

CALL WS-PROGRAMA
USING WS-COMMAREA.

CALL 'VALIDA01'
USING BY CONTENT WS-DATA.

CALL 'ROTINA99'
USING BY REFERENCE WS-BLOCO.

Neste momento surge a dúvida existencial:

Por que existem tantos tipos de CALL?

Qual é o mais rápido?

Qual gasta menos memória?

O que acontece dentro do z/OS?

O compilador faz mágica?

O Load Module engorda?

Como um banco executa milhões de CALLs por segundo sem explodir?

Prepare seu café.

Vamos abrir a tampa do motor do z/OS.


O que é um CALL?

Simplificando:

CALL significa pedir ajuda para outro programa.

Em vez de colocar 100 mil linhas em um único fonte, quebramos o sistema em pequenas peças reutilizáveis.

Por exemplo:

Programa principal

PROCESSA-CLIENTES

chama

VALIDA-CPF

CALCULA-JUROS

GERA-BOLETO

ENVIA-MQ

ATUALIZA-DB2

Cada um especializado.

É praticamente microserviços.

Só que inventados em 1960.


Por que IBM fez isso?

Porque memória custava uma fortuna.

Década de 70

Memória podia custar mais que um carro.

Era necessário:

reutilizar código

economizar memória

compartilhar lógica

facilitar manutenção

Assim nasceu o CALL.


Anatomia de um programa COBOL

Um programa COBOL compilado produz:

Objeto

Binder

Load Module

PDs Loadlib

Execução

Exemplo:

SYS1.LOADLIB


PROCESSA
VALIDA
JUROS
CPFCHK

O Padawan descobre o Static CALL

Exemplo

CALL 'VALIDA'

Simples.

Mas o compilador já conhece VALIDA.

Ele avisa o Binder:

Inclua VALIDA aqui.


O que acontece no LinkEdit

Binder faz:

PROCESSA


+

VALIDA


+

CPFCHK


+

JUROS


=

EXECUTÁVEL FINAL

Na memória

Antes:

PROCESSA

Depois:

PROCESSA


VALIDA


CPFCHK


JUROS

Tudo junto.

Tudo carregado.


Vantagens

Performance

Excelente.

Não precisa procurar.

Não precisa abrir bibliotecas.

Não precisa localizar módulo.

É praticamente:

BALR

Menor CPU

Menos instruções.

Menos overhead.

Menos I/O.


Desvantagens

Executável cresce.

Muito.

Exemplo

Programa principal

1 MB

Subrotinas

500 KB

Total

1,5 MB


Imagine 200 subrotinas.

Seu módulo vira um Godzilla.


Problema clássico

Padawan:

"Troquei VALIDA"

Produção:

Ainda usa antiga.

Porque precisa relinkar.


Quando usar?

Sempre que:

Programa nunca muda

Alta performance

Rotina crítica

Batch pesado

Exemplo:

Juros

Cálculo tributário

Validação interna


O Dynamic CALL aparece

Padawan evolui.

Descobre:

01 WS-PGM PIC X(8).

MOVE 'VALIDA' TO WS-PGM.

CALL WS-PGM.

O que acontece?

COBOL não sabe quem será chamado.

Somente em execução.


Busca do módulo

zOS procura:

STEPLIB

JOBLIB

LPA

LINKLIST


Exemplo

CALL CPFCHK

Sistema:

Existe?

Não.

Próximo.

Existe?

Sim.

Carrega.

Executa.


Vantagens

Flexibilidade absurda.

Pode trocar programas.

Sem recompilar.

Sem binder.

Sem relink.


Plugins COBOL

Exemplo

Cartão VISA

MOVE 'VISA0001'

Master

MOVE 'MASTER01'

PIX

MOVE 'PIX00001'

Mesmo sistema.

Rotinas diferentes.


Desvantagens

Procura programa.

Mais CPU.

Mais I/O.

Mais tempo.


Mas é lento?

Depende.

Primeira chamada.

Sim.

Segunda.

Muito rápida.

Porque pode ficar residente.


O segredo da residência

zOS é esperto.

Se programa está em memória.

Reutiliza.

Não busca novamente.


Comparação

Static

Casa própria

Dynamic

Airbnb

O executável cresce?

Static

Sim.

Dynamic

Não.

Executável principal fica pequeno.


Exemplo

Static

PROCESSA

1.5 MB

Dynamic

PROCESSA

600 KB

Subrotinas externas.


O que é mais performático?

Resposta curta.

Static.

Fim.

Mas...


O que é melhor?

Depende.

Banco.

Static.

Framework.

Dynamic.

Produtos.

Dynamic.

Rotinas financeiras.

Static.


Como o CALL funciona internamente?

Imagine isto.

Programa principal

00001000
PROCESSA

Subrotina

00025000
VALIDA

CALL executa

Guardar endereço retorno


Ir para 25000


Executar


Voltar

É praticamente um GOTO sofisticado.

Só que elegante.


Erros clássicos

S806

Programa não encontrado.

Mensagem

IEC806I

Causa

Módulo ausente.

STEPLIB errada.

Nome inválido.


S0C1

Executou lixo.

Programa corrompido.


S0C4

Endereço inválido.

Muito comum em parâmetros errados.


Como descobrir

SDSF

JESMSGLG

SYSOUT


Verificar:

STEPLIB

SYSLIB

LOADLIB


Easter Egg IBM

Muitos bancos possuem:

PROG0001

PROG0002

PROG0003

Ninguém sabe o que fazem.

Autor aposentou em 1998.

Documentação desapareceu.

Programa continua funcionando.

Todos têm medo de alterar.

É chamado:

Código Arqueológico Mainframe™


Dicas Bellacosa Mainframe

Dica 1

Static para alta frequência.


Dica 2

Dynamic para produtos.


Dica 3

Nunca fazer:

MOVE WS-USUARIO TO WS-PGM

CALL WS-PGM

Sem validar.

Pode chamar qualquer coisa.

Inclusive algo inexistente.


Dica 4

Validar sempre.

EVALUATE WS-PGM

WHEN 'CPFCHK'

WHEN 'JUROS01'

WHEN 'PIX0001'

WHEN OTHER

DISPLAY 'INVALIDO'

END-EVALUATE

Dica 5

Logar chamadas.

DISPLAY 'CALL=' WS-PGM

Ajuda muito.


A Filosofia Jedi do CALL

O Padawan iniciante pensa:

CALL serve apenas para executar outro programa.

O desenvolvedor intermediário pensa:

CALL serve para reutilizar código.

O Mestre Mainframe entende:

CALL é uma decisão arquitetural.

Ele impacta:

  • CPU

  • Memória

  • Tempo de resposta

  • Tamanho do Load Module

  • Facilidade de manutenção

  • Segurança

  • Escalabilidade

  • Observabilidade

  • Estratégia de deploy

E é exatamente por isso que, cinquenta anos depois, os sistemas bancários que movimentam bilhões de dólares diariamente ainda utilizam a mesma instrução COBOL que um programador digitou em um terminal verde na década de 1970:

CALL 'SUBPGM'

Na próxima etapa da jornada, o Padawan descobrirá que o verdadeiro poder do COBOL não está apenas em chamar programas, mas em como os dados atravessam a fronteira entre eles, mergulhando nos mistérios de BY REFERENCE, BY CONTENT, BY VALUE, ponteiros, Work-Storage, Local-Storage e Language Environment, onde vivem os temidos S0C4, os buffers compartilhados e os segredos que fazem alguns programas parecerem mágicos aos olhos dos desenvolvedores mais jovens.

domingo, 20 de dezembro de 2009

🔥🧠 COBOL no z/OS — COMO O PROGRAMA “EXISTE” NA MEMÓRIA (DO SUBMIT AO FREEMAIN) 🧠🔥

 
Bellacosa Mainframe explica uso de storage de um programa Cobol Batch do sub até o Freemain

🔥🧠 COBOL no z/OS — COMO O PROGRAMA “EXISTE” NA MEMÓRIA (DO SUBMIT AO FREEMAIN) 🧠🔥

Uma visão completa — arquitetura + runtime + storage + troubleshooting — exatamente como um Dev Mainframe precisa entender 😎

Baseado na arquitetura de memória virtual do z/OS (VSM/RSM/ASM, áreas common/private, DAT, etc.) .


🚀 VISÃO GERAL — A JORNADA DO PROGRAMA COBOL

👉 Um programa COBOL no mainframe não é carregado “na RAM” diretamente como em PCs.

Ele passa por:

JCL → JES → Initiator → Address Space → Loader → LE → Execução → Término → Liberação

Programa Cobol uso de storage 



🧭 PASSO 1 — SUBMIT DO JCL

Quando você faz:

//STEP1 EXEC PGM=MEUPROG

O que acontece:

1️⃣ JES2/JES3 recebe o job
2️⃣ JCL é interpretado
3️⃣ Recursos são reservados
4️⃣ Job entra na fila

👉 Nenhuma memória do programa ainda foi alocada.


🏗️ PASSO 2 — CRIAÇÃO DO ADDRESS SPACE

Quando o job inicia:

👉 O z/OS cria um Address Space dedicado

Esse espaço virtual contém:

  • Áreas privadas do job

  • Áreas comuns compartilhadas

  • Estruturas do sistema


🧠 Estrutura simplificada

COMMON STORAGE (global)
-----------------------
PRIVATE STORAGE (do job)

📏 PASSO 3 — POSIÇÃO NA MEMÓRIA (LINE / BAR)

🔻 Below the Line (24-bit)

0 → 16 MB
👉 Legacy (raramente usado por COBOL moderno)


🔸 Above the Line (31-bit)

16 MB → 2 GB
👉 Onde vive a maioria dos programas COBOL batch


🔺 Above the Bar (64-bit)

2 GB
👉 Dados grandes, LE heaps modernos, Java, DB2 buffers etc.


🧠 Onde um COBOL típico roda?

👉 Código geralmente em 31-bit
👉 Dados podem estar 31-bit ou 64-bit


🧩 PASSO 4 — QUEM CARREGA O PROGRAMA?

🏆 Loader do z/OS (Program Fetch)

Fluxo:

1️⃣ Initiator chama o programa
2️⃣ Loader procura módulo em:

  • STEPLIB

  • JOBLIB

  • LNKLST

  • LPA (se residente)

3️⃣ Módulo é carregado na memória virtual


📦 Onde o código fica?

Normalmente:

👉 Private storage do address space
👉 Ou LPA se compartilhado (read-only)


🧠 PASSO 5 — LINGUAGE ENVIRONMENT (LE)

Programas COBOL modernos executam sob LE.

O LE cria:

  • Stack

  • Heap

  • Control blocks

  • Runtime services

  • Condition handlers


🧱 Heaps do LE

Podem ficar:

  • Below the bar

  • Above the bar (HEAP64)

  • Mixed


⚙️ PASSO 6 — EXECUÇÃO

Durante a execução o programa usa:

🔹 Código (reentrante)

Read-only, pode ser compartilhado

🔹 WORKING-STORAGE

Dados globais do programa

🔹 LOCAL-STORAGE

Dados por chamada

🔹 FILE BUFFERS

Buffers de I/O

🔹 LE heaps

Alocações dinâmicas


🧠 Quem gerencia a memória?

🔷 VSM — Virtual Storage Manager

👉 Alocação virtual (GETMAIN/STORAGE)

🔶 RSM — Real Storage Manager

👉 Mapeamento para memória física

🔷 ASM — Auxiliary Storage Manager

👉 Paging se necessário


📊 VISÃO INTERNA SIMPLIFICADA

Address Space do Job

├─ User Region
│ ├─ Código COBOL
│ ├─ WORKING-STORAGE
│ ├─ LE Heap/Stack
│ └─ Buffers

├─ LSQA
│ └─ Control blocks locais

└─ COMMON (CSA/SQA/LPA)
└─ Componentes globais

🔄 PASSO 7 — CHAMADAS ENTRE PROGRAMAS

Quando um COBOL faz:

CALL 'OUTROPGM'

Pode ocorrer:

🔹 Static call

Módulo já carregado

🔹 Dynamic call

Loader traz novo módulo

👉 Pode alocar mais storage.


🧵 PASSO 8 — PAGING (SE NECESSÁRIO)

Se memória física faltar:

👉 Páginas podem ir para auxiliary storage

Transparente para o programa.


🏁 PASSO 9 — TÉRMINO DO PROGRAMA

Quando termina:

1️⃣ LE executa rotinas de cleanup
2️⃣ Arquivos são fechados
3️⃣ Storage privado é liberado
4️⃣ Control blocks são removidos


🧹 PASSO 10 — LIBERAÇÃO DO ADDRESS SPACE

👉 O sistema destrói o espaço virtual do job.

Tudo que não é comum desaparece.


📊 WORKFLOW COMPLETO

SUBMIT

JES Queue

Initiator seleciona job

Criação do Address Space

Loader carrega programa

LE inicializa runtime

Execução COBOL

I/O e alocações dinâmicas

Finalização

Liberação de storage

Address Space destruído


Como funciona um Cobol Batch no Mainframe



💣 TROUBLESHOOTING — VISÃO DO DEV COBOL

🔥 S878 — falta de storage

Causas típicas:

  • Loop de alocação

  • Heaps grandes

  • REGION pequeno

  • Vazamento via LE


🔥 0C4 — proteção

  • Ponteiro inválido

  • Overlay

  • Uso após FREEMAIN

  • Dados corrompidos


🔥 S40D — region pequena

  • Muitos buffers

  • Tabelas grandes

  • Recursão

  • LE heap insuficiente


🧠 DICAS DE OURO PARA DEV MAINFRAME

✔ Código reentrante economiza memória

Pode ser compartilhado entre jobs.


✔ Usar LOCAL-STORAGE reduz interferência

Cada invocação tem sua cópia.


✔ Dados gigantes → considerar ABOVE THE BAR

Via LE e opções de compilação.


✔ Evitar loops de alocação dinâmica


🏆 RESUMO FINAL — QUEM FAZ O QUÊ?

ComponenteFunção
JESGerencia job
InitiatorExecuta
LoaderCarrega programa
LERuntime COBOL
VSMMemória virtual
RSMMemória real
ASMPaging
z/OSOrquestra tudo

🎯 CONCLUSÃO

👉 Um programa COBOL não “fica na memória” —
ele vive dentro de um ecossistema sofisticado de virtualização.

Entender isso permite:

💎 Diagnosticar ABENDs difíceis
💎 Otimizar performance
💎 Dimensionar REGION corretamente
💎 Conversar de igual para igual com SysProg
💎 Evoluir para arquiteto de plataforma

https://www.linkedin.com/pulse/cobol-zos-como-o-programa-existe-na-mem%25C3%25B3ria-do-submit-bellacosa-xliaf


terça-feira, 27 de fevereiro de 2007

Chamando Subprogramas em COBOL – Tipos de comandos CALL

 

Bellacosa Mainframe e o comando CALL e subprogramas em COBOL

Chamando Subprogramas em COBOL – Tipos de comandos CALL

Um dos recursos mais importantes do COBOL é a capacidade de dividir uma aplicação em vários módulos menores chamados:

Subprogramas

Isso permite reutilização de código, manutenção mais simples e melhor organização das aplicações Mainframe.


O que é um Subprograma?

É um programa COBOL que é chamado por outro programa.


Estrutura

Programa Principal
        ↓
     CALL
        ↓
   Subprograma
        ↓
     GOBACK
        ↓
Programa Principal

Exemplo Simples

Programa Principal:

CALL 'CALCULA'.

Subprograma:

IDENTIFICATION DIVISION.
PROGRAM-ID. CALCULA.

PROCEDURE DIVISION.

DISPLAY 'ENTREI NO SUBPROGRAMA'.

GOBACK.

Resultado:

ENTREI NO SUBPROGRAMA

Tipos de CALL

Existem vários tipos de chamada.


1. CALL Estático

O nome do programa é conhecido durante a compilação.

CALL 'CALCULA'

Características:

✅ Mais rápido

✅ Verificação na Linkedição

✅ Muito usado em Batch


Fluxo:

MAIN
 ↓
CALL 'CALCULA'
 ↓
CALCULA

2. CALL Dinâmico

O nome do programa está em uma variável.

01 WS-PGM PIC X(8).

MOVE 'CALCULA' TO WS-PGM.

CALL WS-PGM.

Características:

✅ Flexibilidade

✅ Escolha em tempo de execução

✅ Muito usado em frameworks


Fluxo:

WS-PGM
   ↓
CALCULA
VALIDA
CONSULTA

Exemplo

IF TIPO = 'A'

   MOVE 'CALCA' TO WS-PGM

ELSE

   MOVE 'CALCB' TO WS-PGM

END-IF

CALL WS-PGM

3. Nested Program Call

Programa interno chamando outro.

IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN.

PROCEDURE DIVISION.

CALL 'SUB1'.

PROGRAM-ID. SUB1.

CALL 'SUB2'.

Fluxo:

MAIN
 ↓
SUB1
 ↓
SUB2

4. CALL Recursivo

Um programa chama ele próprio.

Necessário:

RECURSIVE PROGRAM

Exemplo:

IDENTIFICATION DIVISION.
PROGRAM-ID. FATORIAL
RECURSIVE.

Fluxo:

FATORIAL
    ↓
FATORIAL
    ↓
FATORIAL

5. CALL para Módulos LE

Chamada de rotinas do Language Environment.

Exemplo:

CALL 'CEE3ABD'

Usado para:

  • ABEND controlado

  • Datas

  • Hora

  • Serviços LE


6. CALL para Rotinas Assembler

Muito comum em Mainframe.

CALL 'ROTASM01'

Fluxo:

COBOL
 ↓
ASSEMBLER
 ↓
COBOL

7. CALL para CICS

Em CICS normalmente usamos:

EXEC CICS LINK
     PROGRAM('PROG2')
END-EXEC.

Ou

EXEC CICS XCTL
     PROGRAM('PROG2')
END-EXEC.

LINK x XCTL

LINK

Retorna ao chamador.

PROG1
 ↓
LINK
 ↓
PROG2
 ↓
Retorna

XCTL

Não retorna.

PROG1
 ↓
XCTL
 ↓
PROG2

Passagem de Parâmetros

O mais comum.


Programa Principal

CALL 'CALCULA'
USING WS-VALOR.

Subprograma

LINKAGE SECTION.

01 LK-VALOR PIC 9(5).

PROCEDURE DIVISION USING LK-VALOR.

Fluxo

MAIN
 ↓
USING
 ↓
LINKAGE

Múltiplos Parâmetros

Programa Principal:

CALL 'CALCULA'

USING

   WS-NOME
   WS-SALDO
   WS-DATA.

Subprograma:

PROCEDURE DIVISION USING

   LK-NOME
   LK-SALDO
   LK-DATA.

BY REFERENCE

Padrão do COBOL.

Passa endereço.

CALL 'PROG1'

USING BY REFERENCE WS-NOME.

Pode alterar o valor original.


BY CONTENT

Passa cópia.

CALL 'PROG1'

USING BY CONTENT WS-NOME.

Não altera a variável original.


BY VALUE

Passa valor diretamente.

Muito usado em integração com C.

CALL 'PROG1'

USING BY VALUE WS-CODIGO.

Exemplo

MOVE 100 TO WS-VALOR

CALL 'TESTE'

USING BY CONTENT WS-VALOR

Subprograma altera:

MOVE 500 TO LK-VALOR

Resultado:

WS-VALOR = 100

CANCEL

Remove programa da memória.

CANCEL 'CALCULA'

Muito usado após CALL dinâmico.


Fluxo

CALL
 ↓
Executa
 ↓
CANCEL
 ↓
Memória liberada

CALL e Load Modules

O programa chamado precisa estar:

STEPLIB
JOBLIB
LINKLIST
LPA

Erros Comuns

S806

Programa não encontrado.

S806

U4038

Erro interno.


S0C4

Parâmetro incorreto.


Boas Práticas

✅ Usar GOBACK nos subprogramas

✅ Validar parâmetros recebidos

✅ Documentar USING

✅ Evitar excesso de níveis CALL

✅ Utilizar COPYBOOK para parâmetros


Exemplo Corporativo

MAIN
 │
 ├── VALIDA
 │
 ├── CONSULTA-DB2
 │
 ├── CALCULA-JUROS
 │
 ├── GERA-ARQUIVO
 │
 └── LOG-ERRO

Cada módulo é um subprograma especializado.


Resumo Rápido

TipoCaracterística
CALL EstáticoNome fixo
CALL DinâmicoNome variável
NestedPrograma dentro de programa
RecursivoChama a si próprio
LINK CICSRetorna
XCTL CICSNão retorna
BY REFERENCEPassa endereço
BY CONTENTPassa cópia
BY VALUEPassa valor
CANCELRemove da memória

Conclusão

O comando CALL é o mecanismo que permite a modularização das aplicações COBOL. Através dele, programas podem compartilhar regras de negócio, reutilizar código e organizar grandes sistemas corporativos em componentes menores. Dominar CALL estático, dinâmico, parâmetros USING, BY REFERENCE, BY CONTENT, BY VALUE, LINK, XCTL e CANCEL é essencial para qualquer programador COBOL que deseje atuar em ambientes Mainframe modernos.

segunda-feira, 26 de fevereiro de 2007

O que é o comando GOBACK em COBOL?

 

Bellacosa Mainframe e o comando Goback em Cobol

O que é o comando GOBACK em COBOL?

O comando GOBACK é utilizado para encerrar a execução de um programa ou retornar o controle para o programa chamador.

Ele é considerado uma das instruções mais importantes do COBOL moderno e, em muitos ambientes, substitui o uso de STOP RUN.


Definição Simples

O GOBACK significa:

Volte para quem me chamou

ou, se não existir programa chamador:

Termine a execução

Sintaxe

GOBACK.

Exemplo Simples

IDENTIFICATION DIVISION.
PROGRAM-ID. TESTE.

PROCEDURE DIVISION.

DISPLAY 'OLA MUNDO'.

GOBACK.

Resultado:

OLA MUNDO

Programa finalizado.


Como Funciona?

O comportamento depende da forma como o programa foi executado.


Programa Principal

Executado por JCL:

//STEP1 EXEC PGM=PROG1

Fluxo:

JCL
 ↓
PROG1
 ↓
GOBACK
 ↓
Fim da execução

Subprograma

Programa principal:

CALL 'SUBROT1'.

Subprograma:

DISPLAY 'ENTREI'.

GOBACK.

Fluxo:

MAIN
 ↓
CALL SUBROT1
 ↓
GOBACK
 ↓
MAIN continua

Exemplo Completo

Programa Principal:

IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN.

PROCEDURE DIVISION.

DISPLAY 'ANTES'.

CALL 'SUB1'.

DISPLAY 'DEPOIS'.

GOBACK.

Subprograma:

IDENTIFICATION DIVISION.
PROGRAM-ID. SUB1.

PROCEDURE DIVISION.

DISPLAY 'SUBPROGRAMA'.

GOBACK.

Saída:

ANTES
SUBPROGRAMA
DEPOIS

GOBACK x STOP RUN

Essa é a comparação mais importante.

GOBACKSTOP RUN
Retorna ao chamadorFinaliza tudo
Seguro para subprogramasPerigoso em subprogramas
Recomendado atualmenteUso tradicional
Funciona em programas chamadosEncerra toda aplicação

Exemplo Visual

GOBACK

MAIN
 ↓
SUB1
 ↓
GOBACK
 ↓
MAIN continua

STOP RUN

MAIN
 ↓
SUB1
 ↓
STOP RUN
 ↓
Tudo termina

Uso em Batch

Muito comum.

OPEN INPUT ARQCLI

PERFORM PROCESSA

CLOSE ARQCLI

GOBACK.

Uso em Subprogramas

É a principal recomendação.

CALL 'CALCULO'

CALL 'VALIDA'

GOBACK.

Uso em Programas DB2

Também é amplamente utilizado.

IF SQLCODE NOT = 0

   DISPLAY SQLCODE

   GOBACK

END-IF.

GOBACK e Return Code

Pode ser combinado com:

MOVE 8 TO RETURN-CODE.

GOBACK.

Resultado:

CC=0008

GOBACK e Language Environment

No ambiente LE (Language Environment), o GOBACK é tratado de forma inteligente.

Se existir chamador:

Retorna ao chamador

Se não existir:

Finaliza execução

EXIT PROGRAM x GOBACK

Outro comando relacionado.


EXIT PROGRAM

EXIT PROGRAM.

Retorna apenas ao chamador.


GOBACK

GOBACK.

Retorna ao chamador ou termina a aplicação.


Comparação

ComandoFunção
EXIT PROGRAMRetorna ao chamador
GOBACKRetorna ou termina
STOP RUNFinaliza tudo

Exemplo com EXIT PROGRAM

IDENTIFICATION DIVISION.
PROGRAM-ID. SUB1.

PROCEDURE DIVISION.

DISPLAY 'SUB'.

EXIT PROGRAM.

Boas Práticas

✅ Utilize GOBACK em subprogramas

✅ Utilize GOBACK em programas novos

✅ Defina RETURN-CODE quando necessário

✅ Evite STOP RUN em módulos chamados

✅ Padronize o encerramento dos programas


Erros Comuns

STOP RUN em subprograma

CALL 'SUB1'

SUB1:

STOP RUN.

Resultado:

Aplicação inteira termina

Não retornar código

GOBACK.

Sem:

MOVE 8 TO RETURN-CODE

Pode dificultar automação.


Curiosidades

1. O GOBACK foi introduzido para simplificar o retorno de programas chamados

2. É amplamente recomendado pela IBM para novos desenvolvimentos

3. Funciona perfeitamente com Language Environment (LE)

4. É um dos comandos mais encontrados em aplicações COBOL modernas

5. Em muitos padrões corporativos, STOP RUN é proibido em subprogramas


Resumo Rápido

ConceitoFunção
GOBACKRetorna ao chamador ou termina
STOP RUNFinaliza toda aplicação
EXIT PROGRAMRetorna ao chamador
CALLChama subprograma
RETURN-CODECódigo retorno
LELanguage Environment
BatchUso comum
SubprogramaComando recomendado

Conclusão

O GOBACK é o comando de encerramento mais flexível do COBOL moderno. Ele permite que um subprograma retorne ao programa chamador sem interromper toda a aplicação e, quando executado em um programa principal, encerra normalmente a execução. Por isso, é considerado a melhor prática para o desenvolvimento COBOL em ambientes z/OS, CICS, IMS e DB2.

quinta-feira, 1 de fevereiro de 2007

O que é Paradigma de Programação Procedural?

 

Bellacosa Mainframe e o paradigma de programação procedural

O que é Paradigma de Programação Procedural?

Quando estudamos:

  • COBOL;

  • C;

  • PL/I;

  • Assembler;

  • programação no mainframe;

um dos conceitos mais importantes é o:

paradigma procedural.

Ele dominou o desenvolvimento corporativo durante décadas e ainda hoje é extremamente utilizado no ambiente:

z/OS IBM Z.


Primeiro: o que é paradigma?

Paradigma é:

um modelo ou estilo de programação.

Ele define:

  • como o programa será organizado;

  • como a lógica será construída;

  • como o fluxo será executado.


O que significa “procedural”?

Procedural vem de:

procedimentos.

Ou seja:
o programa é dividido em:

  • rotinas;

  • módulos;

  • procedimentos;

  • etapas organizadas.


Definição simples

Programação procedural é:

um paradigma baseado em procedimentos que executam tarefas passo a passo.

O programa normalmente:

  • segue sequência;

  • manipula variáveis;

  • altera estados;

  • executa rotinas.


Analogia simples

Imagine uma empresa.

Cada setor possui um procedimento:

  • financeiro;

  • RH;

  • cobrança;

  • estoque.

Cada procedimento executa:

uma tarefa específica.

O paradigma procedural funciona assim.


Relação com paradigma imperativo

O procedural é:

um tipo de programação imperativa.

Porque ele também diz:

como fazer as tarefas.


O que muda?

No procedural:

o código é organizado em procedimentos.


Exemplo simples

INICIO
   VALIDAR CLIENTE
   CALCULAR SALDO
   GERAR RELATORIO
FIM

Cada etapa é um:

procedimento.


Como isso aparece no COBOL?

Muito fortemente.


Exemplo COBOL procedural

PROCEDURE DIVISION.

MAIN-PROCESS.
    PERFORM VALIDAR-CLIENTE
    PERFORM CALCULAR-SALDO
    PERFORM GERAR-RELATORIO
    STOP RUN.

O que é PERFORM?

Comando COBOL usado para:

executar procedimentos.


Exemplo dos procedimentos

VALIDAR-CLIENTE.
    DISPLAY 'VALIDANDO'.

CALCULAR-SALDO.
    DISPLAY 'CALCULANDO'.

GERAR-RELATORIO.
    DISPLAY 'GERANDO'.

Isso é programação procedural

O sistema:

  • chama procedimentos;

  • executa etapas;

  • controla fluxo.


Estrutura clássica procedural

ENTRADA
 ↓
VALIDAÇÃO
 ↓
PROCESSAMENTO
 ↓
ATUALIZAÇÃO
 ↓
RELATÓRIO
 ↓
FIM

Características do paradigma procedural


Código dividido em procedimentos


Fluxo sequencial


Uso intenso de variáveis


Alteração de estado


Reutilização de rotinas


Forte controle do fluxo


Como procedural aparece no mainframe?

Praticamente em tudo:

  • COBOL batch;

  • utilitários;

  • JCL procedural;

  • automações;

  • sistemas financeiros.


O COBOL é procedural?

Tradicionalmente:

sim.

Especialmente:

  • COBOL batch clássico;

  • sistemas legados.


Por que procedural fez tanto sucesso no mainframe?

Porque funciona muito bem para:

  • processamento batch;

  • regras de negócio;

  • arquivos sequenciais;

  • grandes volumes de dados.


Exemplo real batch procedural

LER ARQUIVO
 ↓
VALIDAR REGISTRO
 ↓
CALCULAR VALOR
 ↓
ATUALIZAR DB2
 ↓
GERAR RELATÓRIO

O que é modularização?

Dividir programa em partes menores.


Exemplo

ROTINA-LEITURA
ROTINA-CALCULO
ROTINA-IMPRESSAO

Isso facilita:

  • manutenção;

  • testes;

  • reutilização;

  • organização.


O que é subprograma?

Programa chamado por outro programa.

Muito comum em COBOL.


Exemplo

CALL 'CALCSAL'

O que é parâmetro?

Informação enviada para procedimento/subprograma.


Exemplo

CALL 'CALCSAL' USING SALARIO

Procedural vs Orientado a Objetos


Procedural

Organiza:

procedimentos.


Orientado a Objetos

Organiza:

objetos/classes.


Procedural vs Declarativo


Procedural

Diz:

como executar.


Declarativo

Diz:

o que deseja obter.


Exemplo SQL

SELECT NOME
FROM CLIENTES

Mais declarativo.


Exemplo procedural equivalente

LER CLIENTE
SE NOME EXISTE
   MOSTRAR

Vantagens do paradigma procedural


Fácil entender fluxo


Excelente para batch


Ótimo desempenho


Muito eficiente em mainframe


Bom para regras de negócio


Muito estável


Desvantagens


Sistemas grandes ficam complexos


Muito acoplamento


Código repetitivo


Difícil manutenção em programas enormes


GO TO excessivo gera spaghetti code


O que é spaghetti code?

Código confuso cheio de desvios.

Muito famoso em sistemas antigos COBOL.


Curiosidades incríveis

1. Grande parte do sistema bancário mundial ainda usa lógica procedural


2. Muitos programas COBOL possuem décadas de evolução procedural


3. Procedural dominou a computação corporativa por muitos anos


4. O COBOL procedural continua extremamente relevante


Erros comuns de iniciantes


1. Criar procedimentos gigantes


2. Não modularizar


3. Usar GO TO demais


4. Misturar lógica demais em uma única rotina


Dicas importantes

Divida programas em pequenas rotinas


Use PERFORM corretamente


Nomeie procedimentos claramente


Organize fluxo do programa


Como isso aparece no dia a dia?

Praticamente em:

  • COBOL;

  • batch;

  • DB2 procedural;

  • processamento financeiro;

  • faturamento;

  • folha salarial.


Exemplo simplificado completo

MAIN
 ↓
LER CLIENTES
 ↓
VALIDAR DADOS
 ↓
CALCULAR JUROS
 ↓
ATUALIZAR DB2
 ↓
GERAR RELATÓRIO
 ↓
FIM

Resumo rápido

ConceitoSignificado
ProceduralBaseado em procedimentos
PERFORMExecuta rotina COBOL
CALLChama subprograma
ModularizaçãoDividir programa
FluxoOrdem execução
COBOLPrincipal exemplo procedural

Conclusão

O paradigma procedural é um dos modelos mais importantes da programação tradicional no ambiente mainframe IBM Z.

Ele organiza programas em procedimentos e rotinas reutilizáveis, permitindo criar sistemas batch eficientes, estáveis e capazes de processar enormes volumes de dados no z/OS.


Vagner Renato Bellacosa, IBM Champion e especialista em IBM Mainframe
IBM Z17 SYSTEM ONLINE
Sobre o autor

Vagner Renato Bellacosa

IBM Champion 2026 • Especialista em IBM Mainframe

Vagner Renato Bellacosa trabalha com IBM Mainframe desde 1988 , é IBM Champion e especialista em COBOL, CICS, Db2, z/OS e IBM Z. Compartilha experiências profissionais, conhecimento técnico, história da computação e práticas do universo mainframe para aproximar novas gerações das tecnologias que sustentam empresas, bancos e governos ao redor do mundo.

IBM Champion IBM Z COBOL CICS Db2 z/OS Mainframe desde 1988
GitHub LinkedIn
Inicializando conteúdo...