Translate

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

segunda-feira, 15 de abril de 2024

COBOL Ponteiros de Memória: Os Cristais Kyber Escondidos do IBM Z – O Despertar da Força dos Ponteiros - Parte I

 

Bellacosa Mainframe e os ponteiros de memoria no COBOL Parte I

COBOL Ponteiros de Memória: Os Cristais Kyber Escondidos do IBM Z

Parte 1 – O Despertar da Força dos Ponteiros

Quando o Padawan Descobre que um Endereço Pode Ser Mais Poderoso que os Dados

Por Bellacosa Mainframe


"O dado é importante. Mas conhecer onde ele vive na memória é conhecer a própria Força."

Mestre Sysprog Bellacosa


Introdução

Existe um momento na jornada de todo desenvolvedor COBOL em que ele acredita já ter visto praticamente tudo.

Aprendeu arquivos.

Aprendeu VSAM.

Aprendeu DB2.

Aprendeu CICS.

Aprendeu tabelas OCCURS.

Aprendeu REDEFINES.

Aprendeu recursão.

Aprendeu programas aninhados.

Aprendeu até THREADSAFE.

Então um dia aparece um código semelhante a este:

01 PTR-CLIENTE      USAGE POINTER.

SET PTR-CLIENTE TO ADDRESS OF WS-CLIENTE.

O jovem Padawan olha para aquilo e pergunta:

Mestre…

COBOL tem ponteiros?

O mestre sorri.

Toma um gole de café.

E responde:

Sim.

E são provavelmente uma das funcionalidades menos conhecidas, mais poderosas e potencialmente mais perigosas disponíveis no IBM Enterprise COBOL.


O grande mito

Existe um mito muito comum.

"COBOL não trabalha com endereços."

Errado.

COBOL trabalha.

Sempre trabalhou.

Só que de forma extremamente controlada.

Enquanto linguagens como C permitem brincar livremente com memória:

int *p;

COBOL diz:

Jovem Padawan...

Se você vai manipular memória...

Faça isso com respeito.


O que é um ponteiro?

Um ponteiro não é um dado.

Ele não contém um nome.

Ele não contém um CPF.

Ele não contém uma data.

Ele contém:

O endereço onde algo está.

Imagine.

Apartamento:

Rua Jedi 500

Apartamento 1001

O apartamento é o dado.

O endereço é o ponteiro.


Exemplo.

Cliente

Nome

Bellacosa

Está armazenado em:

7FFF012345678

O ponteiro guarda:

7FFF012345678

Nada mais.


Por que isso existe?

Porque às vezes queremos acessar memória dinamicamente.

Criar estruturas.

Buffers.

Caches.

Árvores.

Filas.

Listas.

Comunicar com C.

Trabalhar com APIs.

Manipular XML.

Shared Memory.

LE Runtime.


COBOL sempre teve ponteiros?

Não.

COBOL 60

Não.

COBOL 68

Não.

COBOL 74

Não.


A situação começou a mudar com:

COBOL 85


Mais tarde.

IBM Enterprise COBOL.

Introduziu:

USAGE POINTER

ADDRESS OF

BASED

ALLOCATE

FREE


Atualmente.

Enterprise COBOL

4

5

6

6.3

6.4

6.5

Suportam totalmente.


O que é USAGE POINTER?

É o tipo especial que armazena um endereço.

Exemplo.

01 WS-PTR.

   USAGE POINTER.

ou

01 WS-PTR POINTER.

Não faça:

PIC X(08)

Errado.


Não faça:

PIC 9(18)

Errado.


O compilador conhece o formato.

Você não precisa.


ADDRESS OF

Talvez seja a instrução mais importante.

Exemplo.

Temos.

01 WS-CLIENTE.

   05 WS-NOME PIC X(30).

Pegando endereço.

SET WS-PTR

TO ADDRESS OF WS-CLIENTE

Pronto.

Agora.

WS-PTR aponta.

Para WS-CLIENTE.


Visualmente

Antes.

WS-PTR


NULL

Depois.

WS-PTR


0000007FFF123450

Como funciona na memória

Imagine.

Working Storage

ENDEREÇO


1000


WS-NOME


Bellacosa



1030


WS-IDADE


52



1035


WS-PTR

Executamos.

SET PTR

TO ADDRESS OF WS-NOME

Resultado.

PTR


1000

O ponteiro virou.

Uma espécie de GPS.


O que é SET?

SET é o comando utilizado.

Para manipular ponteiros.

Exemplo.

SET PTR

TO ADDRESS OF WS-DADOS

Outro.

SET PTR TO NULL

Muito importante.

Sempre inicializar.


Boa prática.

SET PTR TO NULL

No início.


Primeiro exemplo completo

Passo 1

Criar estrutura

WORKING-STORAGE SECTION.


01 WS-CLIENTE.

   05 WS-NOME.

      PIC X(30).



01 WS-PTR

USAGE POINTER.

Passo 2

Preencher

MOVE 'BELLACOSA'

TO WS-NOME

Passo 3

Capturar endereço

SET WS-PTR

TO ADDRESS OF WS-CLIENTE

Passo 4

Display

DISPLAY 'PONTEIRO OK'

Fim.


O que o compilador faz?

Compilador cria.

Variável especial.

Compatível com arquitetura.

31 bits.

64 bits.


Padawan pergunta.

Mestre...

Então é um hexadecimal?

Resposta.

Sim.

Normalmente.


Exemplo.

0000000012345678

IBM Z e endereçamento

Aqui começa a magia.

IBM Z possui longa história.


AMODE 24

Década 70.

Memória.

16 MB.


AMODE 31

1983

2 GB


AMODE 64

zSeries

Exabytes teóricos.


COBOL acompanha.


Working Storage

Ponteiros podem apontar para:

Working Storage


Local Storage


Heap


Dynamically allocated


LE Areas


Buffers


Stack

Existe outra área.

Stack.

Exemplo.

Função chamada.

STACK



Frame A


Frame B


Frame C

Cada frame.

Possui.

Variáveis.

Retorno.

Contexto.


Ponteiros podem apontar.

Para stack.

Sim.


Mas aqui mora perigo.


O lado sombrio

Imagine.

Procedimento.

Termina.

Stack destruída.


Ponteiro ainda existe.


Aponta.

Para memória inválida.


Chamamos isso.

Dangling Pointer.


Exemplo.

PTR


12345

Memória já morreu.


Resultado.

SOC4.


Heap

Heap é diferente.

Sobrevive.

Mais tempo.


Usado em.

ALLOCATE.

CEEGTST.

GETMAIN.


Mais seguro.


Curiosidade

Muitos programas COBOL bancários.

Nunca usam ponteiros.


Por quê?

Não precisam.


COBOL nasceu.

Para registros.

Arquivos.

Campos fixos.


Ponteiros vieram.

Muito depois.


Vantagens

Extremamente rápidas.

Não copia dados.


Exemplo.

Mover.

1 MB.

Custa.

CPU.


Mover ponteiro.

8 bytes.

Instantâneo.


Onde usar?

Excelente para.

XML

JSON

Árvores

Cache

Filas

MQ

Buffers

APIs

Sockets

C

Metal C


Onde NÃO usar?

Cadastro clientes.

Folha pagamento.

Relatórios.

VSAM simples.

Batch convencional.


Performance

Muito boa.

Quase zero overhead.


Mas.

Erro custa caro.


Um MOVE errado.

Perde registro.


Ponteiro errado.

Pode derrubar programa.


SOC4.


Segurança

Ponteiros são ferramenta poderosa.

Mas perigosos.


Podem causar.

Corrupção memória.

Exposição dados.

Abends.

Memory leaks.


Padawan deve lembrar.

Ponteiro não sabe.

Se memória ainda existe.

Ele apenas acredita.


Curiosidades Bellacosa

Pouquíssimos desenvolvedores COBOL escrevem código com ponteiros diariamente.

Mas os profissionais que trabalham com:

  • Language Environment

  • XML parsers

  • CEEGTST

  • Metal C

  • DB2 internals

  • Middleware

  • MQ exits

  • CICS User Exits

  • z/OS Connect

  • Parsers de alta performance

frequentemente encontram USAGE POINTER, ADDRESS OF, BASED e estruturas dinâmicas escondidas em programas aparentemente inocentes.


O Conselho do Mestre Bellacosa

Imagine que os dados COBOL são sabres de luz.

Você pode segurá-los diretamente.

Pode copiá-los.

Pode movê-los.

Pode validá-los.

Mas um ponteiro é diferente.

Um ponteiro é um mapa para encontrar o sabre.

Ele não contém energia.

Ele não contém plasma.

Ele apenas diz:

"Vá até aquele lugar da memória e você encontrará aquilo que procura."

E essa é justamente a beleza e o perigo dos ponteiros em COBOL.

Eles permitem que o Padawan transcenda a programação tradicional baseada em registros fixos e passe a manipular a própria estrutura da memória do IBM Z.

Mas também ensinam uma das maiores lições do universo mainframe:

O dado pode estar protegido por RACF.

O dataset pode estar catalogado.

O programa pode ser RENT e THREADSAFE.

Mas um ponteiro errado continua tendo o poder de levar até mesmo um Mestre Sysprog ao temido S0C4.

Continua na Parte 2 – BASED, ALLOCATE, CEEGTST e Estruturas Dinâmicas: Construindo Listas Encadeadas no IBM Z.


quinta-feira, 2 de maio de 2019

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

 

Bellacosa Mainframe apresenta o call em cobol parte V

☕💥 A Jornada do Padawan COBOL – Parte 5

Desvendando o Universo dos CALLs no Mainframe

Binder, Link-Edit, FETCH, CANCEL, Program Objects, DLLs, LPA, LINKLIST e os Segredos dos Mestres do z/OS

Ou como descobrir que um CALL pode custar microssegundos, megabytes e algumas noites de sono se você não entender o que acontece depois do compilador

Por Vagner Bellacosa – Bellacosa Mainframe


O dia em que o Padawan descobre que COBOL não gera executáveis

Até agora aprendemos:

✔ Static CALL

✔ Dynamic CALL

✔ By Reference

✔ Reentrância

✔ LE

✔ Heap

✔ Stack

✔ CEEDUMP

Mas existe uma pergunta importante.

Quando fazemos:

CALL 'VALIDA01'

Como exatamente o z/OS encontra este programa?

Onde ele mora?

Quem o carrega?

Quem o remove?

Quem o deixa residente?

Prepare outro café.

Hoje vamos conhecer o Binder.


O Binder

Antigamente chamávamos de:

Link Edit

Linkage Editor

IEWL

Hoje chamamos simplesmente de:

Binder


Ele é o responsável por transformar:

Objeto

em

Programa executável


Visualmente

COBOL Source

↓

IGYCRCTL

↓

Object Module

↓

Binder

↓

Program Object

↓

PDMLIB

O que o Binder faz

Resolve símbolos

Resolve CALL estático

Organiza seções

Cria aliases

Define AMODE

Define RMODE

Otimiza carregamento


Static CALL revisitado

Exemplo

CALL 'CPFVAL'

Binder procura:

CPFVAL

Achou.

Inclui.

Executável cresce.


Visualmente


MAIN


+

CPFVAL


+

JUROS


+

PIX


=


MAINLOAD


Dynamic CALL

Binder ignora.

Não liga.

Não participa.


Em execução.

Sistema procura.


Onde procura?

STEPLIB

Primeiro.


JOBLIB

Depois.


TASKLIB


LPA


LINKLIST


LPDB

Dependendo ambiente


Fluxo


CALL CPFVAL


↓

STEPLIB


↓

JOBLIB


↓

LPA


↓

LINKLIST


↓

Achou


↓

Carrega


↓

Executa


Quanto custa?

Cada busca.

CPU.

I/O.

Tempo.


Pouco?

Sim.

Milhões de vezes?

Muito.


O segredo da LPA

Link Pack Area


Área compartilhada.


Programa carregado

uma vez.


Usado por todos.


Visualmente


LPA


CPFVAL



CLIENTE A


CLIENTE B


CLIENTE C


CLIENTE D


Excelente.


Quando usar?

Rotinas muito chamadas.

Segurança.

Conversão.

Data.

Utilitários.


FETCH

Poucos usam.

Poucos conhecem.

Muito poderoso.


Exemplo

CALL 'IGZCFCC'

Internamente.

Faz FETCH.


FETCH significa

Pré-carregar.


Antes da execução.


Benefício

Evita primeira carga.

Reduz latência.


CANCEL

Um comando subestimado.


Exemplo

CALL WS-PGM


...


CANCEL WS-PGM

O que faz?

Remove programa da memória.


Por que usar?

Liberar storage.

Reinicializar estado.


Exemplo

Subprograma mantém cache.

Quer limpar.

CANCEL 'CACHE001'

Nova chamada.

Programa recarregado.


Cuidado

CANCEL excessivo

mata performance.


DLL no zOS

Sim.

Existe.


Dynamic Link Library.


Program Objects.


LE suporta.


Exemplo

C

COBOL

PLI

Assembler

Compartilhando.


Program Objects

Evolução do antigo Load Module.


Vantagens

Maior tamanho

AMODE 64

Melhor performance

Mais símbolos

Debug


IBM recomenda.

Sempre.


AMODE

Já vimos.

Mas Binder controla.


Exemplo

AMODE(31)


RMODE(ANY)

RMODE

Onde carregar.


RMODE 24

Baixa memória.


RMODE ANY

Qualquer lugar.


Mais flexível.


Alias

Binder pode criar.


Exemplo

Programa

CLIENTE01

Alias

CL001

Mesmo executável.

Dois nomes.


Problemas clássicos

S806

Programa não encontrado.


Verificar

STEPLIB

LPA

LINKLIST

Binder


S0C1

Módulo inválido.


Compilação errada.


U4087

LE.


S878

Sem memória.


Como descobrir

LISTLOAD

AMBLIST

IEWL

IPCS

SDSF


AMBLIST

Ferramenta maravilhosa.

Pouco utilizada.


Permite ver

AMODE

RMODE

Alias

Entradas

Tamanho


Exemplo

AMBLIST LISTIDR

Dica Bellacosa

Sempre guardar map.


Compile

LIST


OFFSET


MAP

Futuro você agradece.


Microbenchmark Jedi

Método

Tempo

Static CALL

0,8 us

Dynamic

2 us

FETCH

1 us

LPA

0,5 us

CANCEL frequente

8 us


Easter Egg Mainframe

Existe em muitos bancos.

Programa chamado.

GENERICA

Dentro.

EVALUATE WS-TIPO


WHEN 001


CALL P001


WHEN 002


CALL P002


WHEN 003


CALL P003


...


WHEN 999


CALL P999


END-EVALUATE

Mais de 900 programas.


Autor

Aposentado.

Documentação

Nenhuma.


Produção

Executa bilhões.

Diariamente.


Ninguém toca.


Conhecido pelos veteranos como:

A Biblioteca de Alexandria do Mainframe™


Checklist Jedi do Binder

✅ Static apenas quando necessário

✅ Dynamic para produtos

✅ Evitar CANCEL excessivo

✅ Preferir Program Objects

✅ Verificar AMODE

✅ Verificar RMODE

✅ Utilizar LPA

✅ Medir CPU

✅ Guardar MAP

✅ Gerar OFFSET

✅ Conhecer AMBLIST

✅ Conhecer Binder


A Filosofia Jedi do CALL – Parte 5

O Padawan iniciante acredita:

O compilador cria o executável.

O desenvolvedor intermediário pensa:

O Binder junta módulos.

O Mestre Mainframe entende:

O Binder é um arquiteto invisível. Ele decide onde o programa viverá, como será carregado, quem poderá compartilhá-lo, quanto storage consumirá e quantos microssegundos serão economizados em milhões de transações.

E é exatamente por isso que alguns arquitetos IBM Z conseguem olhar para um simples:

CALL 'SUBPGM'

E enxergar imediatamente:

  • Binder

  • Program Objects

  • LPA

  • RMODE

  • AMODE

  • FETCH

  • CANCEL

  • LE

  • CPU

  • Storage

  • Cache

  • Concurrency

  • Escalabilidade

Porque no universo do Mainframe, um CALL nunca é apenas um CALL.

É uma decisão de arquitetura que pode continuar impactando sistemas críticos por décadas.


Na Parte 6, o Padawan poderá explorar o nível Mestre: CICS LINK/XCTL, COMMAREA, Channels & Containers, z/OS Connect, APIs REST, Java, JNI, Metal C, MQ, zIIP, SMF 110, Strobe, APA e como os arquitetos modernos integram COBOL com microsserviços e nuvem.


segunda-feira, 15 de janeiro de 2007

O que é “Acima da Linha”, “Acima da Barra” e Endereçamento de Memória 24, 31 e 64 bits no Mainframe?

 

Bellacosa Mainframe e a memoria em mainframe

O que é “Acima da Linha”, “Acima da Barra” e Endereçamento de Memória 24, 31 e 64 bits no Mainframe?

Esse é um dos temas mais importantes — e mais misteriosos — do mundo z/OS.

Quando alguém começa a estudar:

  • JES2;

  • CICS;

  • DB2;

  • storage;

  • performance;

  • programação assembler;

rapidamente encontra frases como:

  • “rodando acima da linha”;

  • “storage abaixo da linha”;

  • “memória acima da barra”.

No começo parece extremamente confuso.

Mas tudo gira em torno de:

como o mainframe organiza memória.


Primeiro: o que é memória no mainframe?

Memória é o espaço usado para:

  • programas;

  • variáveis;

  • buffers;

  • controle do sistema;

  • áreas de trabalho.

O z/OS gerencia isso de forma extremamente organizada.


O problema histórico

Os primeiros mainframes possuíam pouca memória.

Então a IBM criou limites de endereçamento.

Com o tempo:

  • mais memória surgiu;

  • novos limites foram criados;

  • o z/OS evoluiu mantendo compatibilidade histórica.

Resultado:
existem vários “níveis” de memória.


O que significa “endereçamento”?

Endereçamento é:

a capacidade de localizar posições de memória.

Quanto mais bits:

  • maior espaço de memória acessável.


Analogia simples

Imagine memória como:

uma cidade cheia de casas.

O endereço informa:

  • qual casa acessar.

Quanto mais dígitos no endereço:

  • mais casas podem existir.


Endereçamento de 24 bits

Foi um dos primeiros modelos do mainframe.


Quanto consegue endereçar?

2^{24}=16.777.216

Aproximadamente:

16 MB


Isso criou a famosa:

Linha dos 16 MB


O que é “abaixo da linha”?

Toda memória:

abaixo de 16 MB.


O que é “acima da linha”?

Toda memória:

acima de 16 MB.


Visualmente

0 MB
│
├── Abaixo da linha
│
16 MB  ← A LINHA
│
├── Acima da linha
│

Por que isso é importante?

Muitos programas antigos foram escritos para:

memória de 24 bits.

Eles só conseguem trabalhar:

  • abaixo da linha.


Problema clássico

A região abaixo da linha virou:

extremamente disputada.

Porque:

  • sistema;

  • CICS;

  • buffers;

  • programas antigos;

todos queriam espaço ali.


Então surgiu o endereçamento 31 bits

A IBM expandiu o espaço de memória.


Quanto consegue endereçar?

2^{31}=2.147.483.648

Aproximadamente:

2 GB


Mas por que não 32 bits?

Porque 1 bit era usado para controle interno.

Então o z/OS adotou:

31 bits efetivos.


Resultado

Agora existia:

  • memória abaixo da linha;

  • memória acima da linha.

Muito mais espaço disponível.


Visualmente

0 MB
│
├── Abaixo da linha
│
16 MB ← Linha
│
├── Acima da linha
│
2 GB

Então nasceu a “barra”

Quando o z/OS evoluiu novamente para 64 bits, surgiu:

a barra dos 2 GB.


Acima da barra

Tudo acima de:

2 GB.


Visualmente

0 MB
│
├── Abaixo da linha
│
16 MB ← Linha
│
├── Acima da linha
│
2 GB ← Barra
│
├── Acima da barra
│

Endereçamento 64 bits

Com 64 bits, o espaço cresce absurdamente.


Quantidade teórica

2^{64}=18.446.744.073.709.551.616

Quantidade gigantesca de memória.


Resultado prático

O z/OS moderno consegue trabalhar com:

  • enormes caches;

  • gigantescos bancos de dados;

  • workloads massivos;

  • analytics;

  • Java;

  • Linux on Z.


Então resumindo

ConceitoLimite
24 bits16 MB
31 bits2 GB
64 bitsmemória gigantesca

O que é “abaixo da linha”?

Memória:

abaixo de 16 MB.

Muito usada por:

  • programas antigos;

  • áreas críticas do sistema.


O que é “acima da linha”?

Memória:

entre 16 MB e 2 GB.

Usada por:

  • aplicações modernas 31 bits;

  • CICS;

  • DB2;

  • subsistemas.


O que é “acima da barra”?

Memória:

acima de 2 GB.

Usada por:

  • Java;

  • grandes caches;

  • DB2 moderno;

  • aplicações 64 bits.


O que significa storage constraint?

Problema de falta de memória.

Muito comum:

abaixo da linha.


Por que abaixo da linha é crítico?

Porque:

  • espaço pequeno;

  • muitos componentes disputam memória.

16 MB hoje parece minúsculo.


Exemplo clássico

CICS antigos sofriam muito com:

storage below the line.


Como isso aparece no dia a dia?

Mensagens como:

  • SOS;

  • storage shortage;

  • below the line exhausted.


O que é AMODE?

Addressing Mode

Define:
como o programa trabalha com memória.


Exemplos


AMODE 24

Programa trabalha em:
24 bits.


AMODE 31

Programa usa:
31 bits.


AMODE 64

Programa moderno usa:
64 bits.


O que é RMODE?

Residency Mode

Define:
onde o programa deve residir.


Exemplo

RMODE 24

Programa precisa ficar:
abaixo da linha.


Isso ainda existe?

Muito.

Principalmente em:

  • sistemas legados;

  • assembler;

  • módulos antigos.


Curiosidades incríveis

1. Muitos sistemas críticos ainda possuem código 24 bits

Décadas depois.


2. O z/OS mantém compatibilidade histórica absurda

Programas antigos ainda funcionam.


3. “Abaixo da linha” virou expressão clássica no mainframe


4. O endereçamento 64 bits revolucionou o z/OS moderno

Especialmente DB2 e Java.


Erros comuns de iniciantes


1. Pensar que “linha” é física

Ela é apenas:

um limite lógico de memória.


2. Confundir linha e barra

Linha:
16 MB.

Barra:
2 GB.


3. Achar que 24 bits morreu

Ainda existe muito software legado.


4. Ignorar AMODE/RMODE

Isso pode causar erros graves em assembler e linkedição.


Como isso aparece no JCL e programas?

Em:

  • binder;

  • assembler;

  • parâmetros LE;

  • CICS;

  • DB2;

  • dumps;

  • performance tuning.


Por que aprender isso?

Porque isso explica:

  • arquitetura do z/OS;

  • compatibilidade histórica;

  • gestão de memória;

  • performance;

  • problemas clássicos do mainframe.


Resumo rápido

TermoSignificado
Abaixo da linha< 16 MB
Acima da linha16 MB até 2 GB
Acima da barra> 2 GB
24 bitsaté 16 MB
31 bitsaté 2 GB
64 bitsenorme espaço
AMODEmodo de endereçamento
RMODEonde o programa reside

Conclusão

Os conceitos de:

  • abaixo da linha;

  • acima da linha;

  • acima da barra;

  • endereçamento 24, 31 e 64 bits

fazem parte da evolução histórica da memória no z/OS.

Eles mostram como o mainframe IBM conseguiu evoluir durante décadas mantendo compatibilidade com aplicações antigas enquanto expandia capacidade para workloads modernos gigantescos.