Translate

sexta-feira, 24 de julho de 2026

Microsoft COBOL-80 : Quando um Programador COBOL Descobre que a Microsoft Já Vendia Compiladores Antes de Tentar Reiniciar o Universo

 

Bellacosa Mainframe nostalgico relembrando velharias do passado Microsoft Cobol

☕ Um Café no Bellacosa Mainframe

Microsoft COBOL-80 sem Mistérios

Quando um Programador COBOL Descobre que a Microsoft Já Vendia Compiladores Antes de Tentar Reiniciar o Universo

Existe uma antiga lenda tecnológica, preservada em fitas magnéticas, manuais amarelados e salas onde o ar-condicionado jamais foi desligado, segundo a qual a história da Microsoft começou com o Windows.

Essa lenda está errada.

Profundamente errada.

Errada no mesmo nível de um programa COBOL que compila sem erros, executa com MAXCC=0000, produz um relatório impecavelmente formatado e deposita o salário de toda a diretoria na conta do estagiário.

Muito antes do Windows, do Word, do Excel, do Teams, do Azure e daquela mensagem dizendo que o computador será reiniciado em um horário que você não escolheu, a Microsoft era conhecida principalmente como uma fornecedora de linguagens de programação.

E entre essas linguagens existia o Microsoft COBOL-80.

Sim, jovem padawan do mainframe: a Microsoft já vendeu COBOL.

Não um plugin obscuro criado por três monges em um porão. Não um interpretador experimental encontrado em um disquete escrito “NÃO FORMATAR”. Estamos falando de um compilador comercial, documentado e destinado aos microcomputadores que começavam a surgir no final da década de 1970.

As três imagens desta nossa expedição mostram justamente esse pequeno portal temporal:

  1. o manual do Microsoft COBOL-80;

  2. o compilador sendo executado em um ambiente emulado;

  3. o painel frontal de um IMSAI 8080, uma das máquinas mais emblemáticas da primeira geração dos microcomputadores.

Coloque a toalha sobre o ombro, verifique se o café está quente e evite entrar em pânico. Vamos viajar até uma época em que 64 KB eram considerados um universo computacional inteiro.


Bellacosa Mainframe apresenta o Microsoft Cobol

Capítulo 1 — O manual que veio antes do Windows

A primeira imagem apresenta a capa do:

Microsoft COBOL-80 Reference Manual

Na parte inferior aparece:

© Microsoft, 1978

A capa é simples, quase ascética. Não existe fotografia de banco de imagens mostrando executivos sorrindo diante de gráficos. Não há nuvens, robôs, inteligência artificial, transformação digital ou uma seta apontando para o infinito.

Há apenas o nome da empresa, o nome do produto e a expressão reference manual.

Naquela época, o manual era parte essencial da ferramenta.

Hoje, quando um programador não entende um comando, ele pode consultar:

  • documentação on-line;

  • fóruns;

  • vídeos;

  • repositórios;

  • mecanismos de busca;

  • assistentes de inteligência artificial;

  • aquele colega que responde “aqui funciona” e desaparece.

Em 1978, o manual era o oráculo.

Ele precisava explicar os comandos, as estruturas da linguagem, as limitações do compilador, o formato dos arquivos, as mensagens de erro e o processo necessário para transformar um programa-fonte em alguma coisa executável.

Perder o manual era quase tão grave quanto perder o programa.

A documentação não era um complemento decorativo. Era parte do sistema.

Para um programador COBOL iniciante, essa é a primeira grande lição desta viagem:

Linguagem, compilador, sistema operacional e documentação formam um conjunto.

Você não programa apenas “em COBOL”. Você programa usando uma determinada implementação de COBOL, em determinado ambiente, com determinados limites.

Um programa escrito para IBM Enterprise COBOL em z/OS pode utilizar recursos que não existem no Microsoft COBOL-80. Da mesma forma, um programa criado para um compilador de microcomputador pode empregar extensões particulares que não seriam aceitas em outro ambiente.

O COBOL possui padrões, mas os compiladores vivem no mundo real.

E o mundo real gosta de acrescentar opções, restrições, peculiaridades e pequenas armadilhas capazes de manter consultores empregados durante décadas.


Capítulo 2 — A Microsoft antes de dominar as janelas

No imaginário popular, a Microsoft é associada ao sistema operacional Windows.

Entretanto, a empresa nasceu no mundo das linguagens.

Bill Gates e Paul Allen ganharam notoriedade inicial com uma implementação de BASIC para o Altair 8800. Em seguida, a Microsoft ampliou sua oferta de ferramentas de desenvolvimento para diferentes microcomputadores.

Naquele universo, uma empresa de software precisava fornecer aquilo que permitia transformar uma máquina vazia em uma máquina útil:

  • interpretadores;

  • compiladores;

  • montadores;

  • ferramentas de desenvolvimento;

  • rotinas de suporte;

  • bibliotecas.

O Microsoft COBOL-80 fazia parte dessa fase.

O nome “COBOL-80” não significa necessariamente que a linguagem tenha sido criada em 1980. A documentação mostrada é de 1978, e a versão exibida na tela possui uma data de 1980. O número também remete à família de processadores e ao ecossistema de microcomputadores de 8 bits que orbitava máquinas baseadas no Intel 8080 e no Zilog Z80.

Esse detalhe é importante.

O COBOL nasceu no final da década de 1950 para atender necessidades comerciais e administrativas. Inicialmente, sua imagem estava associada a grandes computadores utilizados por governos, bancos, seguradoras e corporações.

O COBOL-80 ajudou a transportar essa mentalidade para os microcomputadores.

Era como pegar uma criatura acostumada a viver em um oceano de salas refrigeradas e convencê-la a morar dentro de uma caixa sobre uma escrivaninha.

A criatura reclamou.

Mas coube.


Bellacosa Mainframe e o lendario processador intel 8080


Capítulo 3 — O que era um microcomputador em 1978?

Hoje, a palavra “microcomputador” pode soar antiga. Entretanto, na década de 1970, ela era quase revolucionária.

Os computadores comerciais tradicionais eram caros, grandes e normalmente operados por equipes especializadas. O acesso podia ocorrer por terminais, cartões perfurados ou lotes de processamento.

O microcomputador surgiu com uma promessa quase subversiva:

Uma pessoa, uma pequena empresa ou uma escola poderá possuir seu próprio computador.

Naturalmente, o “computador pessoal” daquele período não se parecia muito com um notebook moderno.

Muitas máquinas eram adquiridas em kits. Algumas exigiam montagem. Outras chegavam praticamente sem software. Em certos casos, o usuário precisava inserir manualmente um pequeno programa de inicialização utilizando chaves no painel frontal.

Não havia um assistente dizendo:

Olá! Vamos concluir a configuração do seu dispositivo.

Havia luzes.

Havia interruptores.

Havia silêncio.

E havia a certeza de que, se alguma coisa desse errado, o fabricante provavelmente estava a três estados de distância e também não sabia exatamente por que.


Bellacosa Mainframe apresenta o IMSAI 8080

Capítulo 4 — O IMSAI 8080 e o painel que parecia controlar uma nave

A terceira imagem mostra um IMSAI 8080 Microcomputer System.

Observe o nome com atenção: IMSAI, não “MSAI”.

Essa máquina surgiu como um dos sistemas compatíveis com a arquitetura popularizada pelo Altair 8800. Tornou-se uma das imagens clássicas da computação pessoal dos anos 1970 graças ao seu painel frontal repleto de chaves vermelhas e azuis.

Para um observador moderno, o painel parece pertencer a uma nave espacial fabricada por uma civilização que dominava viagens interestelares, mas ainda não havia descoberto o teclado.

As chaves permitiam controlar diretamente operações fundamentais da máquina.

No painel aparecem indicações como:

  • EXAMINE;

  • DEPOSIT;

  • RESET;

  • RUN;

  • STOP;

  • SINGLE STEP;

  • POWER ON;

  • POWER OFF.

Também existem luzes associadas ao barramento de endereços, ao barramento de dados e aos estados de execução.

Vamos traduzir isso para a linguagem de um programador iniciante.

Examine

Permitia observar o conteúdo de uma determinada posição de memória.

Em termos conceituais, era como perguntar:

O que existe neste endereço?

Hoje, um depurador mostra variáveis, registradores, memória e pilha em janelas organizadas. No IMSAI, você examinava os bits por meio das luzes do painel.

Deposit

Permitiria gravar um valor em uma posição de memória.

Era possível selecionar um endereço, definir os bits e depositar um byte.

Depois você avançava para o próximo endereço.

E repetia o processo.

E repetia.

E reconsiderava todas as decisões que o haviam conduzido à carreira de tecnologia.

Single Step

Executava uma instrução por vez.

Esse recurso é ancestral direto do “step into” e do “step over” dos depuradores modernos.

O conceito não mudou:

  1. execute uma instrução;

  2. observe o estado da máquina;

  3. tente compreender o que aconteceu;

  4. culpe o compilador;

  5. descubra que o erro era seu.

Run

Iniciava a execução normal.

Era o equivalente físico de liberar o programa para correr pela memória, carregando consigo toda a confiança injustificada do desenvolvedor.


Capítulo 5 — Digitar programas usando chaves

Nas primeiras configurações, antes de carregar um sistema operacional completo, o usuário podia precisar inserir um pequeno programa inicial diretamente pelo painel.

Esse programa era chamado de bootstrap ou bootstrap loader.

Sua função era carregar algo maior a partir de um dispositivo disponível, como fita de papel, cassete, disquete ou outro meio.

Imagine que você queira carregar um sistema operacional.

Mas para ler o sistema operacional você precisa de um programa.

E esse programa ainda não está na memória.

Logo, você precisa colocar manualmente o primeiro pequeno programa na máquina.

É o equivalente tecnológico de precisar construir uma escada para alcançar o manual que explica como construir escadas.

O operador ajustava as chaves para representar valores binários.

Por exemplo:

00111110

Cada chave correspondia a um bit: zero ou um.

O valor era depositado em uma posição da memória. Depois vinha o próximo byte. Depois o próximo.

Uma sequência errada poderia impedir a inicialização.

Não aparecia:

Syntax error near line 17

A máquina apenas não fazia aquilo que você esperava.

O que, curiosamente, continua sendo o comportamento predominante de grande parte do software moderno.


Capítulo 6 — O emulador e a segunda imagem

A segunda imagem mostra um ambiente que reproduz um computador antigo. Há uma janela de terminal marcada como CRT e uma representação virtual do painel de controle.

Na tela aparecem comandos e nomes de arquivos relacionados ao COBOL.

É possível identificar algo semelhante a:

COBLIB
COBOL
COBOL1
COBOL2
COBOL3
COBOL4

E, mais abaixo:

COBOL-80 V4.01
30-SEP-80
COPYRIGHT 1979,80 (C) MICROSOFT

Essa tela é extraordinária porque materializa o elo entre o manual de 1978 e a execução do compilador.

Não estamos apenas olhando para uma capa histórica. Estamos vendo um software daquela geração sendo executado em um ambiente preservado ou emulado.

A versão apresentada é a 4.01, datada de setembro de 1980.

Isso demonstra que o produto teve evolução. Ele não foi apenas uma experiência isolada lançada em um envelope e imediatamente esquecida atrás de uma copiadora.

O compilador possuía módulos e arquivos auxiliares. Em um ambiente de memória extremamente limitada, programas complexos eram frequentemente divididos em várias fases.

Um compilador precisava realizar tarefas como:

  1. ler o código-fonte;

  2. reconhecer palavras e símbolos;

  3. analisar a estrutura da linguagem;

  4. validar definições;

  5. construir tabelas internas;

  6. gerar código intermediário ou código de máquina;

  7. produzir listagens e mensagens;

  8. integrar rotinas necessárias;

  9. criar um programa executável.

Hoje, podemos imaginar todas essas etapas executadas por um único processo que consome centenas de megabytes.

Naquele período, o compilador precisava trabalhar dentro de um espaço muito menor.

Dividir o processo em módulos não era um capricho arquitetural.

Era sobrevivência.


Capítulo 7 — O universo inteiro dentro de 64 KB

Processadores como o Intel 8080 possuíam um espaço de endereçamento de 16 bits.

Com 16 bits, podemos representar:

2¹⁶ = 65.536

Portanto, o espaço máximo diretamente endereçável era de 65.536 bytes, ou 64 KB.

Mas não conclua que o programador tinha todos esses 64 KB livres.

Dentro desse espaço podiam precisar coexistir:

  • sistema operacional;

  • programa;

  • dados;

  • buffers;

  • pilha;

  • rotinas de entrada e saída;

  • tabelas internas;

  • áreas reservadas ao hardware.

É como alugar um apartamento de 64 metros quadrados e descobrir que 20 metros pertencem ao condomínio, 10 estão ocupados pela caldeira e o compilador decidiu trazer três parentes para morar na sala.

Por isso, eficiência era essencial.

O programador precisava considerar:

  • tamanho dos registros;

  • quantidade de buffers;

  • organização dos arquivos;

  • tamanho do programa;

  • uso de sobreposições;

  • chamadas de módulos;

  • espaço disponível para execução.

Hoje, muitos programadores consideram memória apenas quando o sistema começa a consumir 14 GB para exibir uma lista de clientes.

Naquela época, cada byte tinha currículo, endereço fixo e autorização formal para permanecer no sistema.

Linha do tempo dos microprocessadores dos anos 70

AnoMicroprocessadorBitsClock típicoCuriosidade
1971Intel 40044 bits740 kHzPrimeiro microprocessador comercial do mundo
1972Intel 80088 bits500–800 kHzPrimeiro CPU de uso mais geral da Intel
1974Intel 80808 bits2 MHzRevolucionou os microcomputadores
1974Motorola 68008 bits1 MHzGrande concorrente do 8080
1975MOS Technology 65028 bits1 MHzMuito barato e extremamente popular
1976Zilog Z808 bits2,5–4 MHzCompatível e superior ao 8080
1978Intel 808616 bits5–10 MHzInício da arquitetura x86
1979Motorola 6800016/32 bits8 MHzMuito à frente do seu tempo

Capítulo 8 — Como o COBOL cabia em uma máquina dessas?

O COBOL é uma linguagem conhecida por sua verbosidade.

Um programa simples pode conter:

IDENTIFICATION DIVISION.
PROGRAM-ID. OLA-MUNDO.

PROCEDURE DIVISION.
    DISPLAY "NAO ENTRE EM PANICO".
    STOP RUN.

À primeira vista, parece estranho executar uma linguagem tão descritiva em um computador tão pequeno.

Entretanto, o código-fonte não permanece necessariamente inteiro na memória durante a execução. O compilador transforma as instruções COBOL em uma representação executável mais compacta.

Algumas implementações também utilizavam bibliotecas de runtime.

Por exemplo, quando o programa executava uma operação complexa, o compilador poderia gerar uma chamada para uma rotina pronta, em vez de repetir toda a implementação em cada programa.

Considere:

MULTIPLY VALOR BY TAXA GIVING RESULTADO.

O compilador poderia gerar instruções nativas ou recorrer a rotinas auxiliares, dependendo dos tipos de dados e da arquitetura.

Operações decimais eram especialmente importantes para sistemas comerciais.

COBOL não existe apenas para somar números. Ele existe para somar números da maneira esperada por contadores, bancos, governos e departamentos financeiros, criaturas conhecidas por considerar um centavo incorreto motivo suficiente para convocar uma reunião de cinco horas.


Capítulo 9 — O primeiro programa de nossa expedição

Vamos imaginar um pequeno programa de cadastro comercial compatível com a filosofia da época.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. CLIENTE.

       DATA DIVISION.
       WORKING-STORAGE SECTION.

       01 WS-NOME       PIC X(30).
       01 WS-SALDO      PIC 9(5)V99.
       01 WS-SALDO-ED   PIC ZZZZ9.99.

       PROCEDURE DIVISION.

           DISPLAY "NOME DO CLIENTE: ".
           ACCEPT WS-NOME.

           DISPLAY "SALDO: ".
           ACCEPT WS-SALDO.

           MOVE WS-SALDO TO WS-SALDO-ED.

           DISPLAY "CLIENTE: " WS-NOME.
           DISPLAY "SALDO: " WS-SALDO-ED.

           STOP RUN.

Mesmo esse programa simples contém vários conceitos fundamentais.

IDENTIFICATION DIVISION

Identifica o programa.

PROGRAM-ID. CLIENTE.

Em ambientes COBOL modernos, o nome do programa pode participar de chamadas, carregamento e organização do executável.

DATA DIVISION

Define os dados utilizados.

01 WS-NOME PIC X(30).

O campo recebe até 30 caracteres.

01 WS-SALDO PIC 9(5)V99.

Representa um valor numérico com cinco dígitos inteiros e duas casas decimais implícitas.

O V não ocupa uma posição física. Ele indica onde o ponto decimal deve ser considerado.

PROCEDURE DIVISION

Contém a lógica.

ACCEPT WS-NOME.

Lê um valor.

DISPLAY "CLIENTE: " WS-NOME.

Apresenta uma informação na tela.

Para um iniciante, esse exemplo ensina a essência do COBOL:

Defina os dados com clareza. Depois descreva o que deve acontecer com eles.

Essa filosofia atravessou gerações de computadores.


Capítulo 10 — Arquivos: onde o COBOL realmente acorda

Exibir “Olá, mundo” é simpático, mas COBOL não conquistou bancos e empresas porque sabia cumprimentar operadores.

Sua força estava no processamento de registros.

Imagine um arquivo sequencial com registros de clientes:

00001ARTHUR DENT                   0000012500
00002FORD PREFECT                 0000042000
00003ZAPHOD BEEBLEBROX            9999999999

Cada parte ocupa uma posição definida.

Um layout COBOL poderia ser:

01 REGISTRO-CLIENTE.
   05 CLIENTE-CODIGO     PIC 9(5).
   05 CLIENTE-NOME       PIC X(30).
   05 CLIENTE-SALDO      PIC 9(8)V99.

Essa organização é uma das razões pelas quais COBOL continua relevante.

O programa descreve precisamente a estrutura dos dados.

Em um sistema empresarial, isso é vital.

Um registro não pode ser interpretado aproximadamente. O saldo não pode “talvez” ocupar oito posições. O código do cliente não pode assumir uma forma emocionalmente conveniente durante a execução.

O dado precisa ter contrato.

E COBOL adora contratos.

Especialmente contratos com cláusulas, subcláusulas, níveis, redefinições e uma 88 para explicar quando alguma coisa significa “SIM”.


Capítulo 11 — Do código até a execução: passo a passo conceitual

O processo exato dependia do ambiente e da versão instalada, mas a jornada geral seria semelhante a esta.

Passo 1 — Criar o código-fonte

O programador utilizava um editor disponível no sistema ou preparava o arquivo em outro ambiente.

O código precisava obedecer às regras de formato aceitas pelo compilador.

Compiladores antigos podiam ser bastante rigorosos quanto a colunas, margens e disposição das linhas.

Passo 2 — Salvar o programa

O arquivo era gravado em um dispositivo disponível, provavelmente um disquete em configurações mais completas.

O espaço era limitado. Não existia o hábito moderno de manter 37 cópias chamadas:

CLIENTE-FINAL.COB
CLIENTE-FINAL2.COB
CLIENTE-FINAL-AGORA-VAI.COB
CLIENTE-FINAL-REAL.COB
CLIENTE-FINAL-REAL-CORRIGIDO.COB

Pelo menos não com a mesma tranquilidade.

Passo 3 — Executar o compilador

O compilador lia o código e produzia mensagens.

Erros poderiam envolver:

  • palavras desconhecidas;

  • divisões ausentes;

  • níveis de dados inválidos;

  • períodos mal posicionados;

  • nomes indefinidos;

  • sentenças incompatíveis;

  • problemas de arquivo.

Passo 4 — Corrigir os erros

O programador consultava a listagem e o manual.

Não havia hiperlink.

Não havia botão “corrigir automaticamente”.

Havia reflexão.

E café.

Principalmente café.

Passo 5 — Gerar ou vincular o programa

Dependendo da implementação, poderia existir uma etapa de linkedição ou geração final, reunindo o código produzido com bibliotecas de execução.

Passo 6 — Executar

Finalmente, o programa era iniciado.

Se tudo estivesse correto, produzia o resultado esperado.

Caso contrário, começava a fase conhecida como:

Agora ficou interessante.


Capítulo 12 — COBOL no microcomputador não era COBOL de brinquedo

É fácil olhar para um computador de 8 bits e imaginar que ele servia apenas para experiências domésticas.

Mas pequenas empresas também precisavam de sistemas.

Elas possuíam:

  • clientes;

  • fornecedores;

  • estoques;

  • contas a receber;

  • contas a pagar;

  • notas;

  • pedidos;

  • folhas de pagamento;

  • relatórios;

  • movimentações.

Essas necessidades eram adequadas ao modelo de processamento do COBOL.

Um microcomputador equipado com discos e software apropriado poderia automatizar atividades que antes exigiriam equipamentos mais caros ou processos manuais.

Eis a verdadeira revolução.

Não era apenas colocar um computador na mesa.

Era permitir que uma organização menor utilizasse conceitos de processamento comercial antes associados a ambientes muito maiores.

O COBOL-80 fazia parte da ponte entre dois mundos:

  • o mundo dos grandes computadores corporativos;

  • o mundo emergente da computação pessoal e departamental.


Capítulo 13 — O que mudou e o que permaneceu igual

Compare o Microsoft COBOL-80 com um ambiente COBOL moderno em IBM Z.

Mudaram:

  • capacidade de memória;

  • velocidade;

  • armazenamento;

  • sistemas operacionais;

  • ferramentas;

  • interfaces;

  • redes;

  • integração;

  • depuração;

  • segurança;

  • automação;

  • volume de transações.

Mas vários conceitos permanecem reconhecíveis:

  • programas;

  • registros;

  • arquivos;

  • campos;

  • processamento sequencial;

  • validação;

  • relatórios;

  • compilação;

  • bibliotecas;

  • módulos;

  • entrada e saída.

Um programador que compreende bem os fundamentos consegue olhar para um programa antigo e reconhecer sua estrutura.

Ele talvez estranhe as limitações, os comandos específicos e a ausência de recursos modernos. Mas a lógica empresarial continua familiar.

Um cliente ainda possui código.

Um produto ainda possui preço.

Uma conta ainda possui saldo.

E o departamento financeiro ainda deseja o relatório para ontem.


Capítulo 14 — Dicas para o programador COBOL iniciante

1. Aprenda primeiro os dados

Antes de tentar dominar todos os comandos, compreenda:

  • PIC X;

  • PIC 9;

  • V;

  • S;

  • níveis 01, 05, 77 e 88;

  • campos editados;

  • campos agrupados;

  • armazenamento decimal e binário.

Em COBOL, compreender os dados vale mais do que decorar cinquenta verbos.

2. Escreva programas pequenos

Comece com:

  • leitura de nome;

  • cálculo de valores;

  • validação;

  • repetição;

  • processamento de uma tabela;

  • leitura de arquivo sequencial.

Não comece tentando reconstruir o sistema financeiro intergaláctico.

Ele já existe e provavelmente está em produção desde 1968.

3. Leia as mensagens do compilador

O compilador costuma fornecer pistas.

Leia:

  • número da linha;

  • severidade;

  • descrição;

  • mensagens anteriores;

  • mensagens posteriores.

Um erro no início do programa pode provocar dezenas de erros derivados.

Corrija primeiro a causa mais antiga.

4. Use nomes claros

Prefira:

WS-VALOR-TOTAL

em vez de:

X1

COBOL foi criado para ser legível.

Não transforme o programa em um enigma apenas para provar que você conhece o alfabeto.

5. Entenda o ambiente

Pergunte:

  • qual compilador?

  • qual versão?

  • qual sistema operacional?

  • qual formato de arquivo?

  • qual codificação?

  • qual runtime?

  • quais extensões são suportadas?

O COBOL não flutua no espaço absoluto. Ele sempre vive em uma plataforma.

6. Respeite programas antigos

Código legado não é automaticamente código ruim.

Muitas vezes ele sobreviveu porque funciona.

Antes de “modernizar”, descubra:

  • quem usa;

  • quais regras implementa;

  • quais arquivos altera;

  • quais sistemas dependem dele;

  • quais exceções acumulou;

  • o que acontece quando falha.

O programa de 1980 pode ser feio.

Mas talvez saiba algo que ninguém mais sabe.


Capítulo 15 — Curiosidades do setor improvável da galáxia

A Microsoft possuía uma identidade muito diferente

No final dos anos 1970, a empresa era amplamente ligada a ferramentas para programadores. O império dos sistemas operacionais para computadores pessoais ainda estava se formando.

O manual COBOL-80 é uma lembrança física dessa fase.

O painel frontal era uma interface de baixo nível real

Não era decoração retrofuturista.

Aquelas luzes e chaves permitiam interagir diretamente com o estado da máquina.

Era uma combinação de console, monitor, depurador e teste de paciência.

64 KB já foram uma quantidade imensa

Muitos sistemas começaram com muito menos memória.

A capacidade máxima teórica não significava que toda máquina estivesse equipada com ela.

Memória custava caro. Adicionar alguns quilobytes poderia representar um investimento sério.

Os disquetes mudaram tudo

Com unidades de disco, tornou-se muito mais prático carregar sistemas operacionais, compiladores e programas.

Sem armazenamento adequado, utilizar uma linguagem como COBOL seria uma aventura consideravelmente mais dolorosa.

O terminal na imagem é virtual

O ambiente moderno está reproduzindo a experiência de uma máquina histórica. Isso permite estudar software antigo sem depender de todo o hardware original.

A emulação é uma espécie de arqueologia executável.

Você não apenas observa o artefato.

Você liga o artefato.


Capítulo 16 — Easter eggs para quem chegou até aqui

Primeiro Easter egg:

O programa de exemplo utilizou nomes como Arthur Dent, Ford Prefect e Zaphod Beeblebrox. Em um sistema comercial real, Zaphod provavelmente seria rejeitado durante o cadastro porque insistiria em possuir duas assinaturas autorizadas e preencheria o campo “quantidade de cabeças” com o valor 2.

Segundo Easter egg:

A frase:

DISPLAY "NAO ENTRE EM PANICO".

é perfeitamente válida como filosofia de programação.

Quando ocorre um erro, o procedimento correto não é entrar em pânico.

É consultar:

  • a mensagem;

  • o código de retorno;

  • a listagem;

  • o dump;

  • os dados de entrada;

  • o manual.

Entrar em pânico consome CPU humana e raramente atualiza o arquivo corretamente.

Terceiro Easter egg:

A toalha é uma ferramenta extremamente útil em um datacenter.

Ela pode servir para:

  • limpar café;

  • proteger um manual;

  • apoiar um teclado;

  • secar lágrimas após um erro de produção;

  • demonstrar que você está preparado para viajar pela infraestrutura corporativa.

Apenas não a coloque sobre a ventilação do equipamento.

Mesmo a literatura cósmica possui limites térmicos.


Capítulo 17 — A verdadeira importância histórica do COBOL-80

O valor do Microsoft COBOL-80 não está apenas em sua raridade ou no charme de executar software antigo.

Ele representa um momento de transição.

O computador estava deixando de ser um recurso exclusivo de grandes organizações e começando a alcançar escritórios menores, escolas, desenvolvedores independentes e entusiastas.

Ao disponibilizar uma linguagem comercial nesse ambiente, o COBOL-80 ajudava a transportar conhecimentos empresariais para uma nova escala de hardware.

Ele mostrava que o microcomputador não precisava servir apenas para jogos, experimentos eletrônicos ou demonstrações.

Ele também poderia processar:

  • faturamento;

  • estoque;

  • clientes;

  • pagamentos;

  • arquivos;

  • relatórios.

Essa transformação ajudou a preparar o terreno para a explosão dos computadores pessoais e dos sistemas administrativos das décadas seguintes.

O COBOL estava descendo do grande altar corporativo e entrando pela porta lateral das pequenas empresas.

Provavelmente carregando uma pasta, um relatório de 132 colunas e uma reclamação sobre o formato do arquivo.


Conclusão — O compilador no fim do universo

As três imagens formam uma narrativa completa.

O manual de 1978 mostra a documentação de uma linguagem comercial produzida por uma Microsoft ainda jovem.

A tela do emulador mostra o COBOL-80 executando, com arquivos, módulos e uma versão datada de 1980.

O IMSAI 8080 mostra o tipo de universo físico ao qual esse software pertencia: uma época de processadores de 8 bits, memória escassa, painéis frontais e interação direta com a máquina.

Para o programador COBOL iniciante, essa história ensina algo fundamental:

COBOL não pertence a uma única máquina.

Ele atravessou mainframes, minicomputadores, microcomputadores, servidores, estações, PCs e ambientes modernos.

Sua forma mudou.

Seus compiladores mudaram.

Suas plataformas mudaram.

Mas seu objetivo central permaneceu surpreendentemente estável: representar dados empresariais com clareza e executar regras de negócio de maneira previsível.

Ao olhar para o Microsoft COBOL-80, não estamos vendo apenas uma curiosidade de museu.

Estamos observando um ancestral.

Uma pequena cápsula histórica de quando a Microsoft vendia compiladores, os computadores conversavam por luzes e o programador precisava saber exatamente onde cada byte estava hospedado.

Naquele tempo, a máquina possuía talvez 64 KB.

Hoje, temos sistemas com terabytes, nuvens globais e modelos de inteligência artificial.

Mesmo assim, em algum escritório, neste exato momento, existe um programa moderno consumindo oito gigabytes de memória para produzir um relatório que um COBOL de 1980 tentaria resolver com um disquete, três módulos, uma listagem impressa e uma expressão silenciosa de reprovação.

Portanto, jovem viajante do Bellacosa Mainframe, guarde esta lição:

A tecnologia avança.

As interfaces mudam.

Os computadores ficam menores, depois maiores, depois virtuais, depois “serverless”, embora continuem utilizando servidores em algum lugar.

Mas as contas precisam fechar.

Os registros precisam ser processados.

Os salários precisam ser pagos.

E, enquanto houver uma empresa, um arquivo e alguém perguntando por que o total não bateu, haverá espaço na galáxia para um programador COBOL segurando um manual, uma toalha e uma caneca de café.

Não entre em pânico.

Confira o PIC.

Bitcoin : Quando um Programador COBOL Descobre que a Maior Criptomoeda do Mundo Não Quebrou... Apenas Parou de Ser Assunto na Mesa do Bar

 

Bellacosa Mainframe e o bitcoin sem misterios e com hds perdidos

☕ Um Café no Bellacosa Mainframe

Bitcoin sem Mistérios

Quando um Programador COBOL Descobre que a Maior Criptomoeda do Mundo Não Quebrou... Apenas Parou de Ser Assunto na Mesa do Bar

"Em 2017 o motorista do táxi queria explicar blockchain para você. Em 2026 ele só quer que o GPS encontre um caminho sem trânsito."


Introdução — O Som do Silêncio Digital

Existe um fenômeno curioso na tecnologia.

Quando uma tecnologia é nova, ela aparece em todo lugar.

Quando amadurece, ela desaparece.

Não porque morreu.

Porque deixou de ser novidade.

Foi exatamente isso que aconteceu com o Bitcoin.

Se você voltar mentalmente para os anos de 2017, 2018, 2020 e principalmente 2021, parecia que a humanidade havia encontrado o Santo Graal financeiro.

Todo mundo falava de Bitcoin.

Seu vizinho.

Seu primo.

Seu barbeiro.

O motorista do Uber.

O motorista do táxi.

O atendente da padaria.

A tia que ainda imprimia e-mails.

O cachorro do vizinho provavelmente possuía uma carteira digital.

Parecia impossível escapar.

Era um verdadeiro spam humano distribuído em blockchain.

Hoje?

Silêncio.

Não porque acabou.

Mas porque aconteceu algo muito mais interessante.

Bitcoin virou infraestrutura.

E infraestrutura nunca recebe aplausos.

Pergunte para qualquer pessoa qual servidor entrega o WhatsApp.

Ninguém sabe.

Pergunte quem fabrica o transformador da rua.

Ninguém sabe.

Pergunte qual sistema controla um banco.

Resposta clássica:

— "Acho que é SAP."

O programador COBOL, sentado discretamente no canto da sala, apenas toma café.


A Febre do Ouro Digital

A humanidade nunca resiste à palavra mágica:

"Dinheiro fácil."

Troque essa frase por qualquer embalagem tecnológica.

Tulipas.

Ouro.

Ações.

NFT.

IA.

Bitcoin.

A história muda de roupa.

Mas continua exatamente igual.

Monty Python provavelmente escreveria assim:


Cena.

Um castelo medieval.

Um cavaleiro anuncia:

— "Encontramos uma moeda mágica!"

Outro pergunta:

— "Ela faz o quê?"

Resposta:

— "Ainda não sabemos."

Todos:

— "COMPREM IMEDIATAMENTE!"


Nada mudou em oitocentos anos.

Apenas substituímos cavalos por GPUs.


O Bitcoin Não Mudou

As pessoas mudaram.

Esse talvez seja o maior mal-entendido da história recente.

O protocolo continua praticamente igual.

Os blocos continuam chegando.

Os mineradores continuam minerando.

A rede continua funcionando.

Sem diretor.

Sem presidente.

Sem gerente.

Sem RH.

Sem reunião no Teams.

Sem PowerPoint.

Sem Scrum Daily.

Imagine explicar isso para um gerente tradicional.

— Quem aprova?

Ninguém.

— Quem manda?

Ninguém.

— Quem é responsável?

Todos.

— Isso não faz sentido.

Exatamente.

Mesmo assim funciona há mais de quinze anos.


Quando Todo Mundo Virou Especialista

Existe uma lei universal.

Quando uma tecnologia chega ao Jornal Nacional...

...já existem especialistas suficientes para ensinar absolutamente tudo sobre ela.

Em poucos meses surgiram:

Especialista em Blockchain.

Especialista em Web3.

Especialista em Criptoativos.

Especialista em Tokenização.

Especialista em Metaverso Financeiro Quântico.

Especialista em Especialistas.

Era impossível abrir o LinkedIn.

Cada perfil dizia:

"Transformando negócios através da descentralização disruptiva da economia exponencial."

Traduzindo:

"Nunca rodei um nó Bitcoin."


A Era das GPUs Desaparecidas

Lembra quando placas de vídeo desapareceram das lojas?

Gamers choravam.

Engenheiros choravam.

Pesquisadores choravam.

Porque alguém havia descoberto que uma RTX fazia dinheiro.

Ou pelo menos parecia fazer.

Casas inteiras viraram estufas.

Galpões.

Containers.

Garagens.

Até quartos.

Pareciam data centers clandestinos.

O consumo elétrico fazia o relógio da concessionária girar tão rápido que parecia ventilador.


Monty Python imaginaria um diálogo:

— Por que sua conta de energia é igual à de uma fábrica de alumínio?

— Estou minerando.

— O quê?

— Dinheiro.

— Com eletricidade?

— Sim.

— Então você transformou energia em dinheiro?

— Exatamente.

— E isso funciona?

— Depende do preço do Bitcoin.

— E quem decide?

— O mercado.

— Quem é o mercado?

Silêncio.

Um peixe entra na sala usando gravata.

Fim da cena.


Os Bancos Descobriram Que Não Era Brincadeira

No começo...

Boa parte do setor financeiro ria.

"Isso nunca substituirá bancos."

Depois começaram a estudar.

Depois abriram departamentos.

Depois contrataram especialistas.

Depois criaram ETFs.

Depois ofereceram custódia.

Depois passaram a vender exatamente aquilo que diziam ser impossível.

A ironia é maravilhosa.

É como um fabricante de máquinas de escrever vendendo notebooks.


O Maior Mito da Mineração

Muita gente acreditava que mineração era imprimir dinheiro.

Na realidade era mais parecido com administrar um data center.

Energia.

Refrigeração.

Hardware.

Troca de equipamentos.

Ruído.

Calor.

Custos.

Quem realmente ganhou dinheiro?

Em muitos casos...

Quem vendia placas de vídeo.

Quem vendia energia.

Quem vendia gabinetes.

Quem vendia ventiladores.

Quem vendia fontes.

Quem vendia cursos ensinando como ganhar dinheiro minerando.

Essa última categoria sempre prospera.


O Disco Rígido de Bilhões

Entramos agora em uma das histórias favoritas da internet.

Pessoas que perderam HDs contendo carteiras Bitcoin.

Algumas histórias ficaram famosas justamente porque envolviam milhares de bitcoins armazenados em discos rígidos descartados anos antes, quando a moeda praticamente não tinha valor.

O roteiro parece filme dos Monty Python.


Cena.

Esposa pergunta:

— Posso jogar esse computador velho fora?

Resposta:

— Claro.

Anos depois.

— Amor...

Lembra daquele HD?

— Sim.

— Acho que tinha alguns bilhões de reais nele.

— Ah.

Silêncio.

Fade out.


Existiram casos documentados de pessoas tentando negociar com cidades inteiras para escavar aterros sanitários em busca de um único disco rígido.

Imagine a reunião.

— Gostaria de cavar metade do lixão municipal.

— Por quê?

— Esqueci minha senha.


Isso parece piada.

Mas aconteceu.

A tecnologia era revolucionária.

Os hábitos humanos continuavam exatamente iguais.


Pendrive: O Cofre do Caos

O pendrive virou uma espécie de Santo Graal moderno.

Pequeno.

Leve.

Discreto.

Também incrivelmente fácil de perder.

Era comum ouvir histórias como:

"Está em algum lugar da casa."

Ou pior.

"Acho que emprestei."

Imagine explicar isso para um arqueólogo do futuro.

"No século XXI algumas pessoas armazenavam fortunas maiores que o orçamento de países em um objeto menor que um chiclete."


O Halving: O Evento que Quase Ninguém Explica Direito

A cada determinado número de blocos, a recompensa dos mineradores é reduzida pela metade.

É como se um programa COBOL executasse automaticamente um:

DIVIDE SALARIO BY 2

Sem perguntar.

Sem sindicato.

Sem reunião.

Sem protesto.

Mesmo assim os mineradores continuam.

Porque o sistema inteiro foi desenhado esperando exatamente isso.

Essa previsibilidade é uma das características mais marcantes do Bitcoin: as regras monetárias são conhecidas de antemão e não mudam ao sabor de decisões políticas de curto prazo.


Por Que Hoje Existe Silêncio?

Porque novidade acabou.

Os curiosos foram embora.

Os aventureiros perderam interesse.

Os especuladores migraram para IA.

Depois para agentes de IA.

Depois para robôs.

Depois para qualquer nova sigla.

Enquanto isso...

Bitcoin continua produzindo blocos.

Mais ou menos como um mainframe.

Quando ninguém fala dele...

É porque provavelmente está funcionando.


O Efeito Mainframe

Existe uma coincidência deliciosa.

Mainframes também desapareceram das conversas.

Mas nunca desapareceram da economia.

Bitcoin passou por algo parecido.

Antes era manchete.

Hoje é infraestrutura financeira para muitos participantes do mercado, com empresas, fundos e serviços especializados operando ao redor dele.

Infraestrutura raramente vira meme.

Ela apenas trabalha.


O COBOL Sorri Discretamente

Imagine um programador COBOL olhando toda essa história.

Ele já viu isso acontecer diversas vezes.

Cliente-servidor.

Java.

XML.

SOA.

Cloud.

Blockchain.

NFT.

IA.

Todo ciclo é parecido.

Primeiro:

"Isso mudará o mundo."

Depois:

"Isso morreu."

Na prática...

Nem uma coisa.

Nem outra.

As tecnologias úteis acabam encontrando um espaço mais estável, enquanto as promessas exageradas ficam pelo caminho.


As Lições Esquecidas

Bitcoin ensinou algumas coisas importantes.

Nem tudo precisa ter um chefe.

Nem todo sistema precisa de uma empresa central.

Nem toda inovação acontece dentro de grandes corporações.

E principalmente...

Guardar senhas continua sendo responsabilidade humana.

A criptografia pode ser praticamente inquebrável.

A memória do usuário...

Nem tanto.


O Ministério das Caminhadas Financeiras

Se Monty Python escrevesse o encerramento, provavelmente seria assim.

Um narrador anuncia solenemente:

"Hoje visitaremos um investidor em Bitcoin."

A câmera abre.

Existe apenas um homem sentado olhando um HD quebrado.

Um padre entra.

Um engenheiro entra.

Um especialista em recuperação de dados entra.

Um arqueólogo entra.

Um geólogo entra.

Um operador de escavadeira entra.

Todos olham para o disco.

Silêncio.

O narrador pergunta:

— Qual é a senha?

O investidor responde:

— Era alguma coisa com aniversário... ou talvez o nome do cachorro... ou a senha do Wi-Fi de 2012...

A câmera corta para um programador COBOL em um CPD.

Ele observa tudo sem alterar a expressão.

Abre um terminal verde.

Digita calmamente:

READY

O lote noturno começa.

Bilhões continuam sendo movimentados.

O sistema continua funcionando.

O Bitcoin continua gerando blocos.

E o HD perdido continua, muito provavelmente, descansando sob toneladas de lixo, observando em silêncio a mais britânica de todas as ironias: a humanidade conseguiu inventar uma moeda descentralizada, matemática e criptograficamente elegante... mas ainda é perfeitamente capaz de perder uma fortuna porque confundiu um disco rígido com sucata.

No fim das contas, talvez essa seja a verdadeira moral da história.

Não foi o Bitcoin que mudou.

Não foram os bancos.

Nem os mineradores.

Foi apenas o ciclo natural das grandes tecnologias. Primeiro elas viram espetáculo, depois viram ferramenta. Quando todos falam delas, normalmente ainda estão sendo descobertas. Quando quase ninguém comenta, é porque, silenciosamente, encontraram seu lugar no mundo.

E, se existe um lugar onde essa lição já era conhecida muito antes da palavra blockchain existir, esse lugar é um CPD de mainframe. Afinal, há décadas os computadores mais importantes do planeta trabalham sem fazer barulho, sem aparecer nas manchetes e sem precisar convencer ninguém de que existem. O Bitcoin, de certa forma, acabou entrando para o mesmo clube: menos conversa, mais funcionamento.


quinta-feira, 23 de julho de 2026

COMP-4 e COMP-5 sem Mistérios — Parte II : Laboratório Prático com TRUNC(STD), TRUNC(OPT), TRUNC(BIN), JCL, Hexadecimal, Testes e Pequenos Acidentes Controlados

Bellacosa Maifnrame com laboratorio pratico cobol comp-4  comp-5


☕ Um Café no Bellacosa Mainframe

COMP-4 e COMP-5 sem Mistérios — Parte II

Laboratório Prático com TRUNC(STD), TRUNC(OPT), TRUNC(BIN), JCL, Hexadecimal, Testes e Pequenos Acidentes Controlados

Na primeira parte, descobrimos que COMP-4 e COMP-5 guardam números em formato binário, mas não fazem exatamente o mesmo contrato com o compilador.

Agora chegou a hora de abandonar a segurança filosófica da teoria e entrar no laboratório.

Nesta segunda parte, faremos o seguinte:

  • criaremos um programa COBOL de testes;

  • compilaremos o mesmo fonte com TRUNC(STD), TRUNC(OPT) e TRUNC(BIN);

  • executaremos três load modules diferentes;

  • mostraremos o conteúdo decimal e hexadecimal dos campos;

  • compararemos COMP-4 com COMP-5;

  • testaremos valores acima do limite do PICTURE;

  • provocaremos truncamentos controlados;

  • analisaremos resultados estranhos;

  • trabalharemos com REDEFINES;

  • estudaremos ON SIZE ERROR;

  • construiremos exercícios para o programador padawan.

O objetivo não é decorar tabelas.

O objetivo é aprender a olhar para um campo COBOL e perguntar:

Quantos dígitos ele declara, quantos bytes ele ocupa e qual dessas duas verdades o compilador utilizará nesta operação?


1. Preparando o laboratório

Utilizaremos um programa chamado:

TRUNCLAB

O mesmo fonte será compilado três vezes.

Cada compilação produzirá um load module:

TRNSTD
TRNOPT
TRNBIN

As opções serão:

TRUNC(STD)
TRUNC(OPT)
TRUNC(BIN)

Depois executaremos os três módulos e compararemos o SYSOUT.

A opção TRUNC afeta a maneira como dados BINARY, COMP e COMP-4 são tratados em movimentos e operações aritméticas. Ela não altera o comportamento de itens COMP-5: para esses campos, o compilador sempre aplica a lógica equivalente a TRUNC(BIN). (IBM)


2. Recordando o tamanho dos campos binários

No Enterprise COBOL, o tamanho físico de um campo binário depende da quantidade de dígitos do PICTURE:

Quantidade de dígitosArmazenamento
1 a 42 bytes
5 a 94 bytes
10 a 188 bytes

Assim:

05 CAMPO-A PIC S9(4) COMP-4.

ocupa 2 bytes.

05 CAMPO-B PIC S9(5) COMP-4.

ocupa 4 bytes.

05 CAMPO-C PIC S9(10) COMP-4.

ocupa 8 bytes.

Os números negativos são representados em complemento de dois, e os dados binários no IBM Z são armazenados em ordem big-endian. (IBM)


3. A tabela que o padawan deve ter ao lado do terminal

Campos de 2 bytes com sinal

PIC S9(1) até PIC S9(4)

Capacidade física:

-32768 até +32767

Campos de 2 bytes sem sinal

PIC 9(1) até PIC 9(4)

Capacidade física:

0 até 65535

Campos de 4 bytes com sinal

PIC S9(5) até PIC S9(9)

Capacidade física:

-2147483648 até +2147483647

Campos de 4 bytes sem sinal

PIC 9(5) até PIC 9(9)

Capacidade física:

0 até 4294967295

Essas faixas representam a capacidade nativa utilizada por COMP-5. Em um campo COMP-4, a opção TRUNC poderá determinar se o programa considera a capacidade decimal do PICTURE ou a capacidade física dos bytes. (IBM)


4. Programa COBOL completo do laboratório

Grave o programa a seguir em um membro como:

USER.COBOL(TRUNCLAB)

O programa contém diferentes grupos de testes.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. TRUNCLAB.

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SOURCE-COMPUTER. IBM-Z.
       OBJECT-COMPUTER. IBM-Z.

       DATA DIVISION.
       WORKING-STORAGE SECTION.

      *---------------------------------------------------------------*
      * IDENTIFICACAO DO LABORATORIO                                  *
      *---------------------------------------------------------------*

       01  WS-TITULO.
           05 FILLER PIC X(45)
              VALUE 'LABORATORIO COBOL - COMP-4, COMP-5 E TRUNC'.

       01  WS-SEPARADOR PIC X(70) VALUE ALL '-'.

      *---------------------------------------------------------------*
      * CAMPOS DE EDICAO                                              *
      *---------------------------------------------------------------*

       01  WS-EDIT-SIGNED    PIC -ZZZ,ZZZ,ZZZ,ZZZ,ZZZ,ZZ9.
       01  WS-EDIT-UNSIGNED  PIC ZZZ,ZZZ,ZZZ,ZZZ,ZZZ,ZZ9.

      *---------------------------------------------------------------*
      * TESTE 1 - HALFWORD COM SINAL                                  *
      *---------------------------------------------------------------*

       01  WS-T1-ENTRADA        PIC S9(9) COMP-5 VALUE ZERO.

       01  WS-T1-COMP4.
           05 WS-T1-C4          PIC S9(4) COMP-4 VALUE ZERO.

       01  WS-T1-COMP4-RAW REDEFINES WS-T1-COMP4.
           05 WS-T1-C4-BYTES    PIC X(2).

       01  WS-T1-COMP5.
           05 WS-T1-C5          PIC S9(4) COMP-5 VALUE ZERO.

       01  WS-T1-COMP5-RAW REDEFINES WS-T1-COMP5.
           05 WS-T1-C5-BYTES    PIC X(2).

      *---------------------------------------------------------------*
      * TESTE 2 - HALFWORD SEM SINAL                                  *
      *---------------------------------------------------------------*

       01  WS-T2-ENTRADA        PIC 9(9) COMP-5 VALUE ZERO.

       01  WS-T2-COMP4.
           05 WS-T2-C4          PIC 9(4) COMP-4 VALUE ZERO.

       01  WS-T2-COMP4-RAW REDEFINES WS-T2-COMP4.
           05 WS-T2-C4-BYTES    PIC X(2).

       01  WS-T2-COMP5.
           05 WS-T2-C5          PIC 9(4) COMP-5 VALUE ZERO.

       01  WS-T2-COMP5-RAW REDEFINES WS-T2-COMP5.
           05 WS-T2-C5-BYTES    PIC X(2).

      *---------------------------------------------------------------*
      * TESTE 3 - EXEMPLO CLASSICO IBM                                *
      *---------------------------------------------------------------*

       01  WS-T3-ENTRADA        PIC S9(9) COMP-5 VALUE ZERO.

       01  WS-T3-COMP4.
           05 WS-T3-C4          PIC S99 COMP-4 VALUE ZERO.

       01  WS-T3-COMP4-RAW REDEFINES WS-T3-COMP4.
           05 WS-T3-C4-BYTES    PIC X(2).

       01  WS-T3-COMP5.
           05 WS-T3-C5          PIC S99 COMP-5 VALUE ZERO.

       01  WS-T3-COMP5-RAW REDEFINES WS-T3-COMP5.
           05 WS-T3-C5-BYTES    PIC X(2).

      *---------------------------------------------------------------*
      * TESTE 4 - FULLWORD                                            *
      *---------------------------------------------------------------*

       01  WS-T4-ENTRADA        PIC 9(10) COMP-5 VALUE ZERO.

       01  WS-T4-COMP4.
           05 WS-T4-C4          PIC 9(6) COMP-4 VALUE ZERO.

       01  WS-T4-COMP4-RAW REDEFINES WS-T4-COMP4.
           05 WS-T4-C4-BYTES    PIC X(4).

       01  WS-T4-COMP5.
           05 WS-T4-C5          PIC 9(6) COMP-5 VALUE ZERO.

       01  WS-T4-COMP5-RAW REDEFINES WS-T4-COMP5.
           05 WS-T4-C5-BYTES    PIC X(4).

      *---------------------------------------------------------------*
      * TESTE 5 - ARITMETICA                                          *
      *---------------------------------------------------------------*

       01  WS-T5-COMP4.
           05 WS-T5-C4          PIC 9(4) COMP-4 VALUE ZERO.

       01  WS-T5-COMP4-RAW REDEFINES WS-T5-COMP4.
           05 WS-T5-C4-BYTES    PIC X(2).

       01  WS-T5-COMP5.
           05 WS-T5-C5          PIC 9(4) COMP-5 VALUE ZERO.

       01  WS-T5-COMP5-RAW REDEFINES WS-T5-COMP5.
           05 WS-T5-C5-BYTES    PIC X(2).

      *---------------------------------------------------------------*
      * TESTE 6 - SIZE ERROR                                          *
      *---------------------------------------------------------------*

       01  WS-T6-COMP4          PIC 9(4) COMP-4 VALUE ZERO.
       01  WS-T6-COMP5          PIC 9(4) COMP-5 VALUE ZERO.
       01  WS-T6-STATUS         PIC X(20) VALUE SPACES.

      *---------------------------------------------------------------*
      * PROCEDURE DIVISION                                            *
      *---------------------------------------------------------------*

       PROCEDURE DIVISION.

       0000-MAIN.

           DISPLAY WS-SEPARADOR
           DISPLAY WS-TITULO
           DISPLAY WS-SEPARADOR

           PERFORM 1000-TESTE-HALFWORD-SIGNED
           PERFORM 2000-TESTE-HALFWORD-UNSIGNED
           PERFORM 3000-TESTE-IBM-HALFWORD
           PERFORM 4000-TESTE-IBM-FULLWORD
           PERFORM 5000-TESTE-ARITMETICA
           PERFORM 6000-TESTE-SIZE-ERROR

           DISPLAY WS-SEPARADOR
           DISPLAY 'FIM DO LABORATORIO'
           DISPLAY WS-SEPARADOR

           GOBACK.

      *---------------------------------------------------------------*
      * TESTE 1                                                       *
      *---------------------------------------------------------------*

       1000-TESTE-HALFWORD-SIGNED.

           DISPLAY SPACE
           DISPLAY 'TESTE 1 - PIC S9(4), VALOR 30000'
           DISPLAY WS-SEPARADOR

           MOVE 30000 TO WS-T1-ENTRADA
           MOVE WS-T1-ENTRADA TO WS-T1-C4
           MOVE WS-T1-ENTRADA TO WS-T1-C5

           MOVE WS-T1-C4 TO WS-EDIT-SIGNED
           DISPLAY 'COMP-4 DECIMAL : ' WS-EDIT-SIGNED
           DISPLAY 'COMP-4 HEX     : '
                   FUNCTION HEX-OF(WS-T1-C4-BYTES)

           MOVE WS-T1-C5 TO WS-EDIT-SIGNED
           DISPLAY 'COMP-5 DECIMAL : ' WS-EDIT-SIGNED
           DISPLAY 'COMP-5 HEX     : '
                   FUNCTION HEX-OF(WS-T1-C5-BYTES).

      *---------------------------------------------------------------*
      * TESTE 2                                                       *
      *---------------------------------------------------------------*

       2000-TESTE-HALFWORD-UNSIGNED.

           DISPLAY SPACE
           DISPLAY 'TESTE 2 - PIC 9(4), VALOR 60000'
           DISPLAY WS-SEPARADOR

           MOVE 60000 TO WS-T2-ENTRADA
           MOVE WS-T2-ENTRADA TO WS-T2-C4
           MOVE WS-T2-ENTRADA TO WS-T2-C5

           MOVE WS-T2-C4 TO WS-EDIT-UNSIGNED
           DISPLAY 'COMP-4 DECIMAL : ' WS-EDIT-UNSIGNED
           DISPLAY 'COMP-4 HEX     : '
                   FUNCTION HEX-OF(WS-T2-C4-BYTES)

           MOVE WS-T2-C5 TO WS-EDIT-UNSIGNED
           DISPLAY 'COMP-5 DECIMAL : ' WS-EDIT-UNSIGNED
           DISPLAY 'COMP-5 HEX     : '
                   FUNCTION HEX-OF(WS-T2-C5-BYTES).

      *---------------------------------------------------------------*
      * TESTE 3                                                       *
      *---------------------------------------------------------------*

       3000-TESTE-IBM-HALFWORD.

           DISPLAY SPACE
           DISPLAY 'TESTE 3 - PIC S99, VALOR 123451'
           DISPLAY WS-SEPARADOR

           MOVE 123451 TO WS-T3-ENTRADA
           MOVE WS-T3-ENTRADA TO WS-T3-C4
           MOVE WS-T3-ENTRADA TO WS-T3-C5

           MOVE WS-T3-C4 TO WS-EDIT-SIGNED
           DISPLAY 'COMP-4 DECIMAL : ' WS-EDIT-SIGNED
           DISPLAY 'COMP-4 HEX     : '
                   FUNCTION HEX-OF(WS-T3-C4-BYTES)

           MOVE WS-T3-C5 TO WS-EDIT-SIGNED
           DISPLAY 'COMP-5 DECIMAL : ' WS-EDIT-SIGNED
           DISPLAY 'COMP-5 HEX     : '
                   FUNCTION HEX-OF(WS-T3-C5-BYTES).

      *---------------------------------------------------------------*
      * TESTE 4                                                       *
      *---------------------------------------------------------------*

       4000-TESTE-IBM-FULLWORD.

           DISPLAY SPACE
           DISPLAY 'TESTE 4 - PIC 9(6), VALOR 1234567891'
           DISPLAY WS-SEPARADOR

           MOVE 1234567891 TO WS-T4-ENTRADA
           MOVE WS-T4-ENTRADA TO WS-T4-C4
           MOVE WS-T4-ENTRADA TO WS-T4-C5

           MOVE WS-T4-C4 TO WS-EDIT-UNSIGNED
           DISPLAY 'COMP-4 DECIMAL : ' WS-EDIT-UNSIGNED
           DISPLAY 'COMP-4 HEX     : '
                   FUNCTION HEX-OF(WS-T4-C4-BYTES)

           MOVE WS-T4-C5 TO WS-EDIT-UNSIGNED
           DISPLAY 'COMP-5 DECIMAL : ' WS-EDIT-UNSIGNED
           DISPLAY 'COMP-5 HEX     : '
                   FUNCTION HEX-OF(WS-T4-C5-BYTES).

      *---------------------------------------------------------------*
      * TESTE 5                                                       *
      *---------------------------------------------------------------*

       5000-TESTE-ARITMETICA.

           DISPLAY SPACE
           DISPLAY 'TESTE 5 - ARITMETICA 9000 + 5000'
           DISPLAY WS-SEPARADOR

           MOVE 9000 TO WS-T5-C4
           MOVE 9000 TO WS-T5-C5

           ADD 5000 TO WS-T5-C4
           ADD 5000 TO WS-T5-C5

           MOVE WS-T5-C4 TO WS-EDIT-UNSIGNED
           DISPLAY 'COMP-4 DECIMAL : ' WS-EDIT-UNSIGNED
           DISPLAY 'COMP-4 HEX     : '
                   FUNCTION HEX-OF(WS-T5-C4-BYTES)

           MOVE WS-T5-C5 TO WS-EDIT-UNSIGNED
           DISPLAY 'COMP-5 DECIMAL : ' WS-EDIT-UNSIGNED
           DISPLAY 'COMP-5 HEX     : '
                   FUNCTION HEX-OF(WS-T5-C5-BYTES).

      *---------------------------------------------------------------*
      * TESTE 6                                                       *
      *---------------------------------------------------------------*

       6000-TESTE-SIZE-ERROR.

           DISPLAY SPACE
           DISPLAY 'TESTE 6 - ON SIZE ERROR'
           DISPLAY WS-SEPARADOR

           MOVE ZERO TO WS-T6-C4 WS-T6-C5
           MOVE SPACES TO WS-T6-STATUS

           COMPUTE WS-T6-C4 =
                   9000 + 5000
               ON SIZE ERROR
                   MOVE 'SIZE ERROR COMP-4' TO WS-T6-STATUS
           END-COMPUTE

           DISPLAY 'STATUS COMP-4  : ' WS-T6-STATUS

           MOVE SPACES TO WS-T6-STATUS

           COMPUTE WS-T6-C5 =
                   9000 + 5000
               ON SIZE ERROR
                   MOVE 'SIZE ERROR COMP-5' TO WS-T6-STATUS
           END-COMPUTE

           DISPLAY 'STATUS COMP-5  : ' WS-T6-STATUS

           MOVE WS-T6-C4 TO WS-EDIT-UNSIGNED
           DISPLAY 'VALOR COMP-4   : ' WS-EDIT-UNSIGNED

           MOVE WS-T6-C5 TO WS-EDIT-UNSIGNED
           DISPLAY 'VALOR COMP-5   : ' WS-EDIT-UNSIGNED.

5. Por que usamos REDEFINES?

Observe:

01  WS-T1-COMP4.
    05 WS-T1-C4 PIC S9(4) COMP-4.

01  WS-T1-COMP4-RAW REDEFINES WS-T1-COMP4.
    05 WS-T1-C4-BYTES PIC X(2).

O REDEFINES não converte o campo.

Ele apenas permite enxergar os mesmos bytes como uma área alfanumérica.

Depois usamos:

FUNCTION HEX-OF(WS-T1-C4-BYTES)

Isso produz uma apresentação hexadecimal dos bytes.

Para o valor decimal 30000, o hexadecimal é:

7530

Em binário:

0111 0101 0011 0000

Como o bit mais significativo é zero, o número é positivo.


6. O hexadecimal que todo padawan deveria reconhecer

Valor decimal 1

Em halfword:

0001

Valor decimal 100

0064

Valor decimal 1000

03E8

Valor decimal 9999

270F

Valor decimal 14000

36B0

Valor decimal 30000

7530

Valor decimal 32767

7FFF

Valor decimal -1

FFFF

Valor decimal -32768

8000

Valor decimal 60000 sem sinal

EA60

O mesmo padrão EA60, se interpretado como um inteiro de 16 bits com sinal, representa um número negativo:

-5536

Aqui está uma das grandes lições do laboratório:

Os bytes não carregam uma pequena placa dizendo “sou signed” ou “sou unsigned”. A declaração COBOL determina como eles serão interpretados.


7. JCL completo usando a procedure IGYWCL

A IBM fornece procedures catalogadas para compilação e linkedição, embora os nomes, parâmetros e bibliotecas possam variar conforme a instalação.

A procedure IGYWCL normalmente executa duas etapas: compila o programa e depois utiliza o objeto gerado para criar o load module na biblioteca indicada por SYSLMOD. (IBM)

No exemplo abaixo, ajuste:

USER.COBOL
USER.LOAD

para os nomes utilizados em seu ambiente.

//TRUNCLAB JOB (ACCT),'BELLACOSA LAB',
//             CLASS=A,
//             MSGCLASS=H,
//             MSGLEVEL=(1,1),
//             NOTIFY=&SYSUID
//*
//*********************************************************************
//* COMPILACAO 1 - TRUNC(STD)
//*********************************************************************
//CSTD     EXEC IGYWCL,
//         PARM.COBOL='LIB,OBJECT,LIST,MAP,XREF,OFFSET,
//         OPT(2),TRUNC(STD)'
//COBOL.SYSIN DD DISP=SHR,DSN=USER.COBOL(TRUNCLAB)
//COBOL.SYSLIB DD DISP=SHR,DSN=USER.COPYLIB
//LKED.SYSLMOD DD DISP=SHR,DSN=USER.LOAD(TRNSTD)
//*
//*********************************************************************
//* COMPILACAO 2 - TRUNC(OPT)
//*********************************************************************
//COPT     EXEC IGYWCL,
//         PARM.COBOL='LIB,OBJECT,LIST,MAP,XREF,OFFSET,
//         OPT(2),TRUNC(OPT)'
//COBOL.SYSIN DD DISP=SHR,DSN=USER.COBOL(TRUNCLAB)
//COBOL.SYSLIB DD DISP=SHR,DSN=USER.COPYLIB
//LKED.SYSLMOD DD DISP=SHR,DSN=USER.LOAD(TRNOPT)
//*
//*********************************************************************
//* COMPILACAO 3 - TRUNC(BIN)
//*********************************************************************
//CBIN     EXEC IGYWCL,
//         PARM.COBOL='LIB,OBJECT,LIST,MAP,XREF,OFFSET,
//         OPT(2),TRUNC(BIN)'
//COBOL.SYSIN DD DISP=SHR,DSN=USER.COBOL(TRUNCLAB)
//COBOL.SYSLIB DD DISP=SHR,DSN=USER.COPYLIB
//LKED.SYSLMOD DD DISP=SHR,DSN=USER.LOAD(TRNBIN)
//*
//*********************************************************************
//* EXECUCAO DO MODULO TRUNC(STD)
//*********************************************************************
//RUNSTD   EXEC PGM=TRNSTD,
//         COND=(4,LT)
//STEPLIB  DD DISP=SHR,DSN=USER.LOAD
//SYSOUT   DD SYSOUT=*
//CEEDUMP  DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//*
//*********************************************************************
//* EXECUCAO DO MODULO TRUNC(OPT)
//*********************************************************************
//RUNOPT   EXEC PGM=TRNOPT,
//         COND=(4,LT)
//STEPLIB  DD DISP=SHR,DSN=USER.LOAD
//SYSOUT   DD SYSOUT=*
//CEEDUMP  DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//*
//*********************************************************************
//* EXECUCAO DO MODULO TRUNC(BIN)
//*********************************************************************
//RUNBIN   EXEC PGM=TRNBIN,
//         COND=(4,LT)
//STEPLIB  DD DISP=SHR,DSN=USER.LOAD
//SYSOUT   DD SYSOUT=*
//CEEDUMP  DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//

Atenção ao PARM

Algumas procedures aceitam:

PARM.COBOL='...'

Outras instalações utilizam parâmetros diferentes ou possuem uma procedure corporativa própria, como:

COBCL
COBOLCL
IGYWCLG
COB6CL

O esqueleto conceitual permanece:

  1. executar o compilador IGYCRCTL;

  2. gerar o objeto em SYSLIN;

  3. executar o binder;

  4. gravar o load module em SYSLMOD;

  5. executar o programa usando STEPLIB.

A IBM documenta IGYCRCTL como o programa compilador e mostra SYSPRINT, SYSLIN, SYSIN e os arquivos SYSUT entre os DDs principais da compilação. (IBM)


8. Versão do JCL sem COPYLIB

Caso o programa não use nenhum COPY, a linha abaixo poderá ser retirada:

//COBOL.SYSLIB DD DISP=SHR,DSN=USER.COPYLIB

Ela foi incluída porque todo laboratório COBOL sério deve estar preparado para o momento em que alguém acrescentará um copybook de 8.000 linhas chamado:

CPYCOMUM

No qual existirão 147 campos, 23 níveis 88 e um comentário de 1996 dizendo:

* NAO ALTERAR - PROVISORIO

9. O comportamento de TRUNC(STD)

TRUNC(STD) aplica-se aos campos receptores BINARY, COMP e COMP-4 em operações como MOVE e expressões aritméticas.

O resultado é ajustado para o número de dígitos declarado no PICTURE do receptor. (IBM)

Considere:

05 WS-DESTINO PIC 9(4) COMP-4.

E:

MOVE 60000 TO WS-DESTINO

O campo físico possui 2 bytes e poderia comportar 60000 sem sinal.

Entretanto, PIC 9(4) descreve apenas quatro dígitos.

Sob TRUNC(STD), a intenção é corrigir o resultado para essa precisão decimal.

Conceitualmente:

60000

será limitado aos quatro dígitos de baixa ordem:

0000

Outro exemplo:

12345

poderá resultar em:

2345

Por que “poderá”?

Porque é necessário considerar exatamente:

  • a declaração do emissor;

  • a declaração do receptor;

  • se o campo é signed ou unsigned;

  • se a operação é MOVE, ADD, COMPUTE ou outra;

  • se existem intermediários;

  • se há otimizações;

  • se foi usado ON SIZE ERROR;

  • a versão do compilador.

Nos casos documentados pela IBM, entretanto, TRUNC(STD) possui comportamento definido de correção à precisão decimal do PICTURE.


10. O comportamento de TRUNC(OPT)

TRUNC(OPT) é uma opção de desempenho.

O compilador assume que os valores enviados aos campos binários obedecem ao PICTURE.

A partir dessa premissa, ele escolhe a sequência de código mais eficiente. Essa sequência poderá corrigir o resultado para os dígitos do PICTURE ou apenas para o tamanho físico de 2, 4 ou 8 bytes. (IBM)

Por isso, não existe uma resposta universal para isto:

05 WS-DESTINO PIC 9(4) COMP-4.

MOVE 60000 TO WS-DESTINO

quando compilado com:

TRUNC(OPT)

O programa está violando a premissa da opção.

60000 não cabe na precisão de PIC 9(4).

A própria IBM afirma que, nessas condições, o resultado pode ser imprevisível e depender da sequência específica de código gerada. (IBM)

Imprevisível aqui não significa que o processador invocará um demônio.

Significa que o programador não deve escrever uma regra funcional contando com determinado resultado.

Uma mudança aparentemente inocente poderá alterar o código gerado:

MOVE WS-ORIGEM TO WS-DESTINO

pode não produzir a mesma sequência interna que:

COMPUTE WS-DESTINO = WS-ORIGEM

Ou:

ADD ZERO TO WS-ORIGEM
    GIVING WS-DESTINO

O compilador otimiza cada construção.


11. O comportamento de TRUNC(BIN)

Com TRUNC(BIN), todos os campos:

BINARY
COMP
COMP-4

são tratados como se fossem COMP-5.

Os receptores são truncados somente no limite físico de:

2 bytes
4 bytes
8 bytes

O conteúdo binário inteiro do campo torna-se significativo. (IBM)

Considere:

05 WS-DESTINO PIC 9(4) COMP-4.

Sob TRUNC(BIN), o campo é tratado como um inteiro binário nativo de 2 bytes sem sinal.

Assim, poderá conter:

60000

porque 60000 cabe no intervalo físico:

0 a 65535

O PICTURE 9(4) continua escrito no programa, mas a magnitude operacional considerada passa a ser a capacidade física do halfword.


12. COMP-5 nos três programas

Este campo:

05 WS-DESTINO PIC 9(4) COMP-5.

terá comportamento nativo independentemente da compilação usar:

TRUNC(STD)
TRUNC(OPT)
TRUNC(BIN)

A opção TRUNC não afeta itens COMP-5. Eles são tratados como se TRUNC(BIN) estivesse em vigor para aquele campo específico. (IBM)

Por isso, no teste:

MOVE 60000 TO WS-T2-C5

esperamos que o conteúdo binário seja:

EA60

E o valor sem sinal seja:

60000

nos três load modules.


13. Análise do teste clássico de halfword

A IBM utiliza um exemplo semelhante a:

01 BIN-VAR PIC S99 USAGE BINARY.

MOVE 123451 TO BIN-VAR

O receptor ocupa 2 bytes porque possui apenas dois dígitos no PICTURE.

O valor decimal 123451 em hexadecimal de quatro bytes é:

0001E23B

Quando apenas a metade inferior é movida para o halfword, permanecem:

E23B

Como o bit de sinal está ligado, o halfword é interpretado como:

-7621

A IBM documenta os seguintes resultados para esse exemplo:

OpçãoValor resultanteHexadecimal
TRUNC(STD)510033
TRUNC(OPT)-7621E23B
TRUNC(BIN)-7621E23B

Com TRUNC(STD), o valor é corrigido para os dois dígitos do PICTURE, resultando em 51.

Com TRUNC(BIN), são preservados os 16 bits inferiores, resultando em E23B, que representa -7621 em complemento de dois.

Nesse caso específico, TRUNC(OPT) escolhe uma sequência eficiente semelhante ao resultado físico de TRUNC(BIN). (IBM)

Aqui está o coração do laboratório.

O valor não “virou negativo por erro”.

Ele virou negativo porque:

  1. o receptor só comportava 16 bits;

  2. ficaram os 16 bits inferiores de 123451;

  3. o padrão resultante foi E23B;

  4. o campo era assinado;

  5. E23B possui o bit de sinal ligado.

O hardware apenas obedeceu.

Como sempre, a máquina é inocente e o copybook possui bons advogados.


14. Análise do teste clássico de fullword

Outro exemplo documentado pela IBM utiliza:

01 BIN-VAR PIC 9(6) USAGE BINARY.

MOVE 1234567891 TO BIN-VAR

PIC 9(6) ocupa quatro bytes.

O valor 1234567891 também cabe fisicamente nos quatro bytes:

499602D3

Os resultados documentados são:

OpçãoValor
TRUNC(STD)567891
TRUNC(OPT)567891
TRUNC(BIN)1234567891

Com TRUNC(STD), são mantidos os seis dígitos definidos pelo PICTURE.

Com TRUNC(OPT), nesse código específico, o compilador escolhe uma sequência que também produz a correção decimal.

Com TRUNC(BIN), o valor completo permanece porque cabe no fullword. (IBM)

Nosso teste 4 reproduz essa situação.


15. O teste aritmético 9000 + 5000

Temos:

05 WS-T5-C4 PIC 9(4) COMP-4.
05 WS-T5-C5 PIC 9(4) COMP-5.

Inicializamos:

MOVE 9000 TO WS-T5-C4
MOVE 9000 TO WS-T5-C5

Depois:

ADD 5000 TO WS-T5-C4
ADD 5000 TO WS-T5-C5

O resultado matemático é:

14000

Hexadecimal:

36B0

14000 cabe fisicamente em 2 bytes sem sinal.

Mas não cabe em PIC 9(4) segundo sua precisão decimal.

Resultado conceitual com TRUNC(STD)

O COMP-4 deverá ser corrigido para quatro dígitos:

4000

Hexadecimal:

0FA0

O COMP-5 poderá manter:

14000

Hexadecimal:

36B0

Resultado com TRUNC(BIN)

Tanto o COMP-4 quanto o COMP-5 deverão usar a capacidade física:

14000

Resultado com TRUNC(OPT)

Não construa uma regra funcional sobre esse teste.

Como os operandos produzem valor superior ao PICTURE, a premissa de TRUNC(OPT) foi violada.

O resultado deverá ser observado no listing e no SYSOUT da versão específica do compilador.

Essa incerteza é deliberada.

É justamente o que o laboratório pretende ensinar.


16. ON SIZE ERROR: a armadilha dentro da armadilha

Observe:

COMPUTE WS-T6-C5 =
        9000 + 5000
    ON SIZE ERROR
        MOVE 'SIZE ERROR COMP-5'
          TO WS-T6-STATUS
END-COMPUTE

O campo WS-T6-C5 é:

PIC 9(4) COMP-5

Fisicamente, ele poderia armazenar 14000.

Porém, existe uma particularidade importante.

Quando ON SIZE ERROR é utilizado em uma operação aritmética cujo receptor é COMP-5, o limite considerado para a condição de tamanho é o valor indicado pelo PICTURE, e não necessariamente toda a capacidade física do recipiente. A IBM documenta explicitamente essa regra. (IBM)

Assim, embora 14000 caiba em dois bytes, ele excede:

PIC 9(4)

Logo, ON SIZE ERROR poderá ser acionado.

Esta é uma das curiosidades mais traiçoeiras de COMP-5.

Sem ON SIZE ERROR:

ADD 5000 TO WS-T5-C5

o recipiente nativo poderá guardar 14000.

Com ON SIZE ERROR:

COMPUTE WS-T6-C5 = 9000 + 5000
    ON SIZE ERROR

o compilador considera a capacidade decimal descrita.

O padawan pergunta:

— Então o campo comporta 14000 ou não comporta?

A resposta mainframe é:

— Fisicamente, sim. Semanticamente, depende da instrução.

E é por isso que COBOL continua empregando analistas experientes.


17. Como analisar o listing de compilação

Depois de compilar, abra o SYSPRINT.

Procure pela seção de opções.

Você deverá encontrar algo semelhante a:

TRUNC=STD

ou:

TRUNC=OPT

ou:

TRUNC=BIN

Nunca confie apenas no JCL submetido.

Uma procedure corporativa pode:

  • acrescentar opções;

  • substituir opções;

  • usar defaults da instalação;

  • carregar parâmetros de outro membro;

  • invocar preprocessadores;

  • alterar a ordem de precedência.

O listing é a evidência final da compilação.

Procure também:

OPTIMIZE
ARCH
TUNE
NUMCHECK
SSRANGE
ARITH
NUMPROC

Essas opções não substituem TRUNC, mas podem ajudar a explicar diferenças de código gerado, diagnóstico e desempenho.


18. Como comparar os três SYSOUTs

Crie uma tabela manual:

TesteTRUNC(STD)TRUNC(OPT)TRUNC(BIN)
S9(4) COMP-4 = 30000AnotarAnotarAnotar
S9(4) COMP-5 = 30000300003000030000
9(4) COMP-4 = 60000AnotarAnotar60000
9(4) COMP-5 = 60000600006000060000
S99 COMP-4 = 12345151-7621*-7621
S99 COMP-5 = 123451-7621-7621-7621
9(6) COMP-4 = 1234567891567891567891*1234567891
9(6) COMP-5 = 1234567891123456789112345678911234567891

O asterisco indica resultados documentados para a sequência específica apresentada pela IBM. TRUNC(OPT) não deve ser tratado como promessa quando o valor não respeita o PICTURE.

A ideia é preencher a tabela com o resultado real de seu ambiente.


19. Exercício 1 — Descubra o tamanho

Sem executar o programa, determine o tamanho dos campos:

05 CAMPO-A PIC S9(3) COMP-4.
05 CAMPO-B PIC S9(4) COMP-5.
05 CAMPO-C PIC S9(5) COMP-4.
05 CAMPO-D PIC 9(9) COMP-5.
05 CAMPO-E PIC S9(10) COMP-4.
05 CAMPO-F PIC 9(18) COMP-5.

Resposta

CAMPO-A = 2 bytes
CAMPO-B = 2 bytes
CAMPO-C = 4 bytes
CAMPO-D = 4 bytes
CAMPO-E = 8 bytes
CAMPO-F = 8 bytes

20. Exercício 2 — Limite decimal ou limite físico?

Considere:

05 WS-NUMERO PIC 9(4) COMP-5.

Responda:

  1. Qual é o máximo sugerido pelo PICTURE?

  2. Qual é o máximo físico do campo?

  3. O valor 50000 cabe fisicamente?

  4. O valor 70000 cabe fisicamente?

Resposta

1. 9999
2. 65535
3. Sim
4. Não

70000 exigiria mais do que os 16 bits disponíveis.

Se armazenado sem diagnóstico adequado, ocorrerá perda de bits ou condição de tamanho, dependendo da operação.


21. Exercício 3 — Signed contra unsigned

Considere os bytes:

EA60

Interprete-os como:

PIC 9(4) COMP-5

e depois como:

PIC S9(4) COMP-5

Resposta

Sem sinal:

60000

Com sinal:

-5536

A diferença não está nos bytes.

A diferença está na interpretação.


22. Exercício 4 — Preveja o hexadecimal

Preencha:

DecimalHexadecimal de 2 bytes
1?
255?
256?
1000?
9999?
32767?
-1?

Resposta

DecimalHexadecimal
10001
25500FF
2560100
100003E8
9999270F
327677FFF
-1FFFF

23. Exercício 5 — Faça o programa falhar de maneira educativa

Acrescente:

01 WS-PEQUENO PIC S9(4) COMP-5 VALUE ZERO.

Depois execute:

COMPUTE WS-PEQUENO = 32767 + 1
    ON SIZE ERROR
       DISPLAY 'SIZE ERROR DETECTADO'
END-COMPUTE

Perguntas:

  1. 32768 cabe em um halfword com sinal?

  2. Qual seria o padrão hexadecimal de -32768?

  3. Por que o bit de sinal é importante?

Respostas

  1. Não. O máximo positivo é 32767.

  2. 8000.

  3. Em um campo com sinal, o bit mais significativo participa da representação do sinal. Ao ultrapassar 7FFF, o padrão seguinte é 8000, interpretado como -32768.


24. Exercício 6 — Troque COMP-4 por COMP-5

Pegue:

05 WS-CONTADOR PIC 9(4) COMP-4.

Altere para:

05 WS-CONTADOR PIC 9(4) COMP-5.

Execute com os valores:

9998
9999
10000
32767
32768
60000
65535
65536

Observe:

  • decimal exibido;

  • hexadecimal;

  • comportamento com ON SIZE ERROR;

  • comportamento sem ON SIZE ERROR;

  • diferença entre compiladores;

  • diferença entre operações MOVE, ADD e COMPUTE.

Este exercício mostra que trocar apenas o USAGE pode alterar o contrato do campo, mesmo que seu tamanho físico permaneça idêntico.


25. Exercício 7 — O campo corrompido pela interface

Simule um programa externo preenchendo bytes diretamente:

01 WS-AREA.
   05 WS-BIN PIC S9(4) COMP-4.

01 WS-AREA-RAW REDEFINES WS-AREA.
   05 WS-RAW PIC X(2).

Depois:

MOVE X'7530' TO WS-RAW

7530 representa:

30000

Agora exiba WS-BIN nos três programas.

Pergunte:

  • TRUNC(STD) alterará os bytes apenas porque o campo foi consultado?

  • DISPLAY utilizará o conteúdo completo?

  • O comportamento muda se fizermos uma operação aritmética?

  • O que acontece se movermos para um campo DISPLAY PIC S9(4)?

  • O que acontece se movermos para PIC S9(5)?

Este teste é valioso porque imita dados colocados por:

  • C;

  • PL/I;

  • Db2;

  • IMS;

  • uma API;

  • um subsystem;

  • uma estrutura compartilhada;

  • um copybook incompatível.

A IBM recomenda TRUNC(BIN) para programas que recebem valores binários definidos por outros produtos quando esses valores podem não respeitar o PICTURE. Alternativamente, pode-se usar COMP-5 apenas nos campos envolvidos na interface. (IBM)


26. Exercício 8 — Encontre o erro de projeto

Analise:

01 LK-PARAMETROS.
   05 LK-BUFFER-LENGTH PIC 9(4) COMP-4.
   05 LK-RETURN-CODE   PIC S9(4) COMP-4.

A interface em C utiliza:

unsigned short buffer_length;
short return_code;

Perguntas:

  1. buffer_length pode chegar a 65535?

  2. PIC 9(4) comunica corretamente essa faixa?

  3. TRUNC(OPT) é seguro caso o programa C envie 60000?

  4. Qual seria uma declaração mais apropriada?

Possível correção

01 LK-PARAMETROS.
   05 LK-BUFFER-LENGTH PIC 9(4) COMP-5.
   05 LK-RETURN-CODE   PIC S9(4) COMP-5.

Melhor ainda, quando a convenção do projeto permitir, documente a faixa:

01 LK-PARAMETROS.
   05 LK-BUFFER-LENGTH PIC 9(5) COMP-5.
   05 LK-RETURN-CODE   PIC S9(5) COMP-5.

Embora aumentar os noves possa alterar o tamanho físico em algumas faixas, a declaração deve ser analisada em conjunto com o tamanho exigido pela interface.

Em interoperabilidade, não basta dizer “é um número”.

É necessário definir:

signed ou unsigned
16, 32 ou 64 bits
big-endian ou little-endian
por valor ou por referência
com ou sem escala decimal
faixa válida
tratamento de overflow

27. NUMCHECK(BIN) como aliado

Em modernizações, a opção NUMCHECK(BIN) pode ajudar a identificar campos binários que contêm valores incompatíveis com o PICTURE.

Ela é especialmente útil quando uma equipe pretende migrar de:

TRUNC(BIN)

para:

TRUNC(OPT)

ou:

TRUNC(STD)

Porém, ela deve ser utilizada conscientemente em testes, porque verificações adicionais podem afetar desempenho.

A documentação da IBM observa que, quando TRUNC(BIN) e NUMCHECK(BIN) são usados juntos, dados fora da precisão decimal podem gerar diagnóstico ou abend, especialmente quando a intenção é posteriormente mudar para TRUNC(STD) ou TRUNC(OPT). (IBM)

Exemplo de compilação para diagnóstico:

PARM.COBOL='LIST,MAP,XREF,TRUNC(BIN),NUMCHECK(BIN)'

Não implemente isso cegamente em produção.

Primeiro execute em ambiente de testes, avalie os diagnósticos e meça o custo.


28. Desempenho: TRUNC(BIN) não é botão de turbo

Pode parecer que TRUNC(BIN) sempre será mais rápido porque utiliza diretamente o tamanho físico.

Mas isso não é uma regra.

Quando todos os campos binários precisam ser tratados como possuindo até 2, 4 ou 8 bytes significativos, o compilador poderá precisar:

  • utilizar intermediários maiores;

  • gerar conversões adicionais;

  • chamar rotinas auxiliares;

  • preservar faixas maiores durante a aritmética.

A IBM mostra que, no Enterprise COBOL 6, TRUNC(OPT) continua sendo uma boa opção geral de desempenho quando os dados realmente obedecem ao PICTURE. Para itens muito grandes, especialmente acima de nove dígitos, TRUNC(BIN) pode exigir processamento adicional. (IBM)

A regra prática é:

Dados obedecem ao PICTURE:
    considere TRUNC(OPT)

Dados externos podem ultrapassar o PICTURE:
    considere COMP-5 nos campos específicos

Programa inteiro depende de binário nativo:
    avalie TRUNC(BIN)

Não escolha uma opção global para corrigir um único campo mal declarado.

Isso seria semelhante a aumentar a pressão de água da cidade porque a torneira da cozinha está entupida.


29. Checklist de investigação de um problema real

Quando encontrar um valor estranho em COMP-4 ou COMP-5, siga esta ordem.

Passo 1 — Veja a declaração

PIC
USAGE
Sinal
V decimal

Passo 2 — Calcule o tamanho físico

2, 4 ou 8 bytes

Passo 3 — Descubra a origem

O valor veio de:

MOVE
ADD
COMPUTE
arquivo
Db2
CICS
IMS
C
PL/I
API
COMMAREA
LINKAGE SECTION
REDEFINES

Passo 4 — Abra o listing

Confirme:

TRUNC(STD)
TRUNC(OPT)
TRUNC(BIN)

Passo 5 — Veja o hexadecimal

Use:

FUNCTION HEX-OF

ou o dump.

Passo 6 — Interprete o sinal

O campo é:

signed
unsigned

Passo 7 — Compare o receptor

O destino consegue representar todo o valor?

Passo 8 — Examine ON SIZE ERROR

A operação usa essa cláusula?

Passo 9 — Reproduza isoladamente

Crie um programa mínimo.

Passo 10 — Não “corrija” antes de entender

Trocar tudo para COMP-5 pode mascarar outro problema:

  • copybook incorreto;

  • interface incompatível;

  • tamanho errado;

  • endianness;

  • campo corrompido;

  • valor funcionalmente inválido.


30. Easter egg: o valor que mudou após a recompilação

Em algum lugar do planeta existe este código:

05 LK-LENGTH PIC 9(4) COMP.

Durante anos, um programa escrito em C colocou nele:

32000

O sistema funcionava.

Ninguém sabia exatamente por quê, mas funcionava, que é a certificação de qualidade mais respeitada em determinados ambientes legados.

Então chegou o projeto de modernização.

O programa foi recompilado com:

TRUNC(STD)

O valor passou a ser tratado de acordo com os quatro dígitos do PICTURE.

A aplicação começou a reservar buffers menores.

Os registros passaram a chegar truncados.

A sala de crise foi aberta.

O gerente perguntou:

— O COBOL 6 está com defeito?

O compilador, representado por seu advogado, respondeu:

— Eu apenas comecei a respeitar o contrato que vocês escreveram.

Depois de quatro horas, alguém alterou:

PIC 9(4) COMP

para:

PIC 9(4) COMP-5

O sistema voltou a funcionar.

O incidente foi encerrado como:

CAUSA RAIZ: COMPORTAMENTO INESPERADO DA PLATAFORMA

Porque escrever:

CAUSA RAIZ: NINGUEM LEU O COPYBOOK

poderia prejudicar o clima organizacional.


31. O que o padawan deve guardar desta prática

TRUNC(STD) prioriza a precisão decimal declarada no PICTURE.

TRUNC(BIN) prioriza a capacidade física de 2, 4 ou 8 bytes.

TRUNC(OPT) prioriza desempenho e pressupõe que o programa respeita o PICTURE.

COMP-5 aplica o comportamento binário nativo ao campo individual, independentemente da opção TRUNC.

REDEFINES não converte: apenas mostra os mesmos bytes por outra janela.

FUNCTION HEX-OF ajuda a enxergar o que realmente está na memória.

ON SIZE ERROR pode considerar o limite decimal do PICTURE, inclusive em determinadas operações com receptores COMP-5.

Valores externos exigem contratos explícitos de tamanho, sinal, ordem dos bytes e faixa.


Conclusão

O verdadeiro laboratório de COMP-4 e COMP-5 não acontece apenas na WORKING-STORAGE.

Ele acontece na fronteira entre três mundos:

O que o PICTURE declara
O que os bytes comportam
O que o compilador decidiu gerar

Em TRUNC(STD), o PICTURE senta-se na cadeira do diretor e exige que os números respeitem a quantidade de dígitos declarada.

Em TRUNC(BIN), o hardware invade a reunião, coloca os 2, 4 ou 8 bytes sobre a mesa e informa que todos os bits serão utilizados.

Em TRUNC(OPT), o compilador olha para o programador e diz:

— Estou assumindo que você sabe o que está fazendo.

Essa talvez seja a frase mais perigosa já pronunciada por uma ferramenta de desenvolvimento.

O programador COBOL padawan precisa aprender a não depender de acidentes históricos. Um programa não deve funcionar porque um determinado compilador gerou, por coincidência, uma sequência favorável.

Ele deve funcionar porque:

  • a declaração corresponde ao dado;

  • a opção de compilação corresponde ao contrato;

  • o tamanho físico é conhecido;

  • a faixa foi testada;

  • a interface foi documentada;

  • os limites foram verificados;

  • o listing foi lido;

  • o hexadecimal foi compreendido.

No mainframe, o número exibido na tela é apenas a superfície.

Nos bastidores existem bits, bytes, sinais, truncamentos, registradores e decisões tomadas pelo compilador em uma sala escura onde nenhum gerente de projeto jamais entrou.

Quando o padawan aprende a enxergar essa camada invisível, COMP-4 e COMP-5 deixam de ser cláusulas misteriosas.

Tornam-se ferramentas precisas.

E, mais importante, deixam de ser o motivo daquela ligação às três da manhã perguntando por que o valor 60000 voltou como 0000, -5536 ou alguma outra manifestação hexadecimal do caos.

O JCL usa nomes genéricos de datasets e uma IGYWCL típica; os parâmetros exatos da procedure devem ser ajustados ao padrão instalado no ambiente z/OS.

☕ Um Café no Bellacosa Mainframe

Viagem ao Fundo do Mar dos Formatos Numéricos COBOL

Uma expedição pelas profundezas de COMP-1, COMP-2, COMP-3, COMP-4 e COMP-5, onde cada byte pode esconder uma criatura binária.

COMP-4 e COMP-5 sem Mistérios Abrir artigo ↗

Descendo aos arquivos do mainframe...