InsidePCV5MANUAL TÉCNICO DA IPC-8
REVISÃO5.0
Manual técnico

Arquitetura IPC-8

Este documento descreve, com precisão suficiente para reimplementar, a máquina didática executada pela bancada do InsidePC. Tudo o que está aqui corresponde ao comportamento real do simulador — as tabelas de instruções e de portas são geradas a partir do próprio motor.

ARQUITETURAAcumulador, 8 bits PALAVRA DE DADOS8 bits ENDEREÇAMENTO16 bits · 64 KB ENDIANESSLittle-endian

1. O modelo da máquina

A IPC-8 é uma máquina de acumulador: quase toda operação aritmética ou lógica usa o registrador A como um dos operandos e como destino do resultado. Essa escolha reduz o número de bits necessários para codificar uma instrução e torna o fluxo de dados fácil de acompanhar visualmente — que é o objetivo do projeto.

Ela segue o modelo de Von Neumann: instruções e dados residem no mesmo espaço de endereçamento e trafegam pelo mesmo barramento. Isso significa que um programa pode, em princípio, sobrescrever a si mesmo — e também que a CPU precisa de fases distintas para buscar instrução e buscar dado.

Consequência prática

Como código e dados dividem o mesmo barramento, a CPU nunca busca uma instrução e um operando ao mesmo tempo. Esse é o chamado gargalo de Von Neumann, e é exatamente o problema que a cache L1 do LAB 04 ameniza.

Blocos funcionais

Unidade de Controle (UC)

Decodifica o opcode presente no IR e gera a sequência de sinais que comanda todos os outros blocos. É ela que define quantos ciclos cada instrução consome.

ALU

Executa soma, subtração, AND, OR, XOR, NOT, deslocamentos e comparação, produzindo o resultado e as quatro flags de condição.

Banco de registradores

PC, IR, MAR, MDR, A, B, SP e o registrador de estado. Todos visíveis na bancada, aba Execução.

Interface de memória e cache

Traduz pedidos de leitura/escrita em ciclos de barramento, consultando antes a cache L1 de mapeamento direto.

2. Bits, bytes e hexadecimal

Um bit é a menor unidade de informação: dois estados possíveis, representados eletricamente por dois níveis de tensão. Oito bits formam um byte, capaz de assumir 256 valores distintos (0 a 255, ou $00 a $FF).

O hexadecimal existe por conveniência humana: cada dígito hexadecimal corresponde exatamente a quatro bits, então um byte é sempre escrito com dois dígitos e um endereço de 16 bits com quatro. Neste manual e na bancada, o prefixo $ indica hexadecimal, % indica binário e # indica um valor imediato.

Conversor interativodigite em qualquer campo

Clique em um bit para invertê-lo. O peso de cada posição aparece abaixo dele.

Complemento de dois

A IPC-8 não distingue números com e sem sinal no armazenamento: o mesmo byte $FF vale 255 se você o interpretar como sem sinal e −1 se interpretar em complemento de dois. Quem decide a interpretação é o programa, olhando para as flags N (bit 7 do resultado) e V (estouro com sinal).

ByteSem sinalCom sinalFlag N
$00000
$7F127+1270
$80128−1281
$FF255−11

3. Registradores

Registradores são as memórias mais rápidas e mais escassas da máquina: ficam dentro do próprio die, ao lado da ALU, e são acessados sem nenhum ciclo de barramento.

RegistradorLarguraFunção
PC16 bitsContador de programa. Aponta para o próximo byte a ser buscado. Alterado por incremento, desvio, chamada, retorno e interrupção.
IR8 bitsRegistrador de instrução. Guarda o opcode que a UC está decodificando neste instante.
MAR16 bitsRegistrador de endereço de memória. O que está no MAR é o que aparece no barramento de endereços.
MDR8 bitsRegistrador de dados de memória. Toda informação que entra ou sai da memória passa por aqui.
A8 bitsAcumulador. Operando principal e destino padrão das operações da ALU.
B8 bitsRegistrador auxiliar. Segundo operando em ADD B, SUB B e destino de TAB.
SP16 bitsPonteiro de pilha. Inicia em $01FF e decresce a cada byte empilhado.
FLAGS4 bitsZ (zero), C (vai-um), N (negativo) e V (estouro com sinal).
IE1 bitHabilitação de interrupção, controlada por EI e DI.
Por que MAR e MDR existem?

Sem eles, o endereço teria de ficar estável no barramento durante todo o acesso enquanto o dado trafega — o que é fisicamente inviável no mesmo conjunto de pinos. O MAR retém o endereço; o MDR retém o dado. Na bancada, o sinal ALE marca exatamente o instante em que o endereço é travado.

4. Formato das instruções e modos de endereçamento

Toda instrução começa por um byte de opcode. O que vem depois — nada, um byte ou dois bytes — depende do modo de endereçamento codificado naquele opcode.

OPCODEImplícito / registrador — 1 byteO operando está subentendido. Ex.: NOT, INC, TAB, ADD B, HLT.
OPCODEIMEDIATOImediato — 2 bytesO valor está no próprio código. Ex.: LDA #$41.
OPCODEPORTAPorta — 2 bytesEndereço de 8 bits no espaço de E/S. Ex.: OUT $10.
OPCODEEND. BAIXOEND. ALTOAbsoluto — 3 bytesEndereço completo de 16 bits, byte menos significativo primeiro. Ex.: LDA $0040.
Little-endian

Em JMP $F0A3, os bytes gravados são 30 A3 F0. A CPU busca primeiro $A3 (parte baixa) e depois $F0 (parte alta), montando o endereço com alto × 256 + baixo. Você pode conferir isso na aba Código da bancada.

Decodificador de instruçãoescolha um opcode

5. Referência completa do conjunto de instruções

A tabela abaixo é gerada diretamente do motor de execução: se uma instrução aparece aqui, ela existe e funciona na bancada. A coluna RTL descreve a operação em Register Transfer Language, a mesma notação exibida no modo engenharia.

Legenda dos modos: imp implícito · reg registrador · imm imediato · port porta de E/S · abs absoluto.

6. A linguagem do montador

O montador integrado faz duas passagens: na primeira, calcula o endereço de cada linha e registra os rótulos; na segunda, resolve as referências e emite os bytes. É por isso que você pode saltar para um rótulo definido mais adiante no arquivo.

Sintaxe

ElementoFormaExemplo
RótuloNOME: no início da linhaLACO: DEC
Comentáriode ; até o fim da linhaHLT ; encerra
Hexadecimal$LDA $40
Binário%AND #%00000001
Decimalsem prefixoLDA #10
Caractereaspas simplesLDA #'K'
Imediato# antes do valorADD #1

Diretivas

DiretivaEfeito
.ORG $F000Define o endereço de montagem das linhas seguintes.
.BYTE $01, 10Emite bytes literais na posição atual.
.WORD $7C00Emite uma palavra de 16 bits em little-endian — usado para preencher vetores.
.ASCII "OK"Emite os códigos ASCII dos caracteres da string.
Vetores obrigatórios

Se o seu programa habilita interrupções, precisa preencher o vetor de IRQ:
.ORG $FFFE seguido de .WORD MINHA_ISR. Sem isso, a CPU desviará para o endereço $0000.

7. O ciclo de instrução

Um processador não “roda um programa”: ele repete indefinidamente um ciclo curto. Todo o resto — sistemas operacionais, navegadores, jogos — é consequência de repetir esse ciclo bilhões de vezes por segundo.

  1. Busca (fetch) — o conteúdo do PC vai para o MAR, o sinal ALE trava o endereço, RD é ativado, a memória devolve um byte pelo MDR e o PC é incrementado.
  2. Decodificação (decode) — o byte passa do MDR para o IR. A UC identifica a operação, o modo de endereçamento e quantos bytes adicionais precisa buscar.
  3. Busca de operando — se o modo exigir, um ou dois bytes extras são buscados da memória, sempre incrementando o PC.
  4. Execução — a ALU calcula, a interface de memória lê ou escreve, ou o PC recebe um novo valor no caso de um desvio.
  5. Escrita (writeback) — o resultado é gravado no destino e as flags são atualizadas.
  6. Verificação de interrupção — se IE estiver ativo e houver IRQ pendente, o contexto é empilhado antes da próxima busca.
Onde ver isso

Na bancada, o painel Ciclo destaca a fase atual e o analisador lógico mostra CLK, ALE, RD, WR e IRQ. Use Shift+→ para avançar uma instrução inteira e → para avançar microoperação por microoperação.

8. Tabela de microoperações

Cada instrução se desdobra em microoperações elementares, executadas em ciclos consecutivos. Abaixo, três exemplos representativos.

LDA $0040 — carga absoluta

TRTLSinaisComentário
T1MAR ← PCALEendereço da instrução no barramento
T2MDR ← M[MAR]RDopcode chega da memória
T3IR ← MDR · PC ← PC+1—decodificação
T4MAR ← PC · MDR ← M[MAR]ALE, RDbyte baixo do endereço
T5MAR ← PC · MDR ← M[MAR]ALE, RDbyte alto do endereço
T6MAR ← alto:baixoALEendereço efetivo montado
T7MDR ← M[MAR]RDleitura do operando (consulta a cache)
T8A ← MDR · flags ← A—escrita no acumulador

ADD B — soma entre registradores

TRTLSinaisComentário
T1–T3busca e decodificaçãoALE, RDidêntico a qualquer instrução
T4ALU ← A, B—operandos nas entradas da ALU
T5A ← A + B—resultado no acumulador
T6flags ← Z,C,N,V—condição do resultado

Atendimento de IRQ

TRTLSinaisComentário
T1IE = 1 ∧ IRQ = 1INTApedido reconhecido ao fim da instrução
T2M[SP] ← PCalto · SP ← SP−1WRempilha retorno
T3M[SP] ← PCbaixo · SP ← SP−1WRempilha retorno
T4M[SP] ← FLAGS · SP ← SP−1WRempilha estado
T5IE ← 0—evita reentrância
T6PC ← M[$FFFE:$FFFF]RDdesvio para a rotina de tratamento

9. A ALU e as flags

A ALU é combinacional: dadas as entradas e a operação, a saída aparece após o atraso de propagação, sem memória interna. O que persiste são as flags, gravadas no registrador de estado ao final da operação.

FlagNomeVale 1 quando…Usada por
ZZeroo resultado é $00JZ, JNZ
CCarryhouve vai-um além do bit 7 (ou empréstimo na subtração)JC, JNC
NNegativoo bit 7 do resultado é 1JN
VOverflowo resultado com sinal saiu da faixa −128…+127testes com sinal
Laboratório da ALUveja as flags reagirem
RESULTADO$2C44 · %00101100

10. Mapa de memória

Os 64 KB endereçáveis não são todos RAM: partes do espaço são reservadas por convenção do firmware, e a faixa superior é ROM — escritas ali são simplesmente ignoradas pelo hardware.

Regiões protegidas

Uma escrita em $F000–$FFFF não gera erro: ela é descartada, exatamente como aconteceria com uma memória somente de leitura real. Se o seu programa parece “não gravar”, verifique se o endereço caiu na ROM.

11. Barramentos e temporização

Barramento é um conjunto de condutores compartilhados. Compartilhar é econômico — menos trilhas na placa — mas exige disciplina: apenas um dispositivo pode dirigir o barramento por vez, e os demais ficam em alta impedância (mostrada na bancada como um padrão hachurado).

BarramentoLarguraSentidoPapel
Endereços16 linhasunidirecional (CPU → memória/E-S)seleciona qual célula ou porta responde
Dados8 linhasbidirecionaltransporta o byte lido ou escrito
Controlesinais discretosmistodefine quando e o quê acontece

Sinais de controle

SinalSignificado
CLKRelógio. Define o compasso; toda transferência ocorre em relação a uma de suas bordas.
ALEAddress Latch Enable. Marca o instante em que o endereço no MAR é considerado válido.
RDLeitura. O dispositivo endereçado deve colocar seu dado no barramento.
WREscrita. O dispositivo endereçado deve capturar o dado presente no barramento.
IO/MSeleciona o espaço de E/S em vez do espaço de memória.
INTAInterrupt Acknowledge. A CPU reconheceu um pedido de interrupção.
HALTA CPU encontrou HLT e parou de buscar instruções.

Custo em ciclos

AcessoCiclosPor quê
Acerto na cache L11o dado já está dentro do die
Falta na cache (RAM)4ciclo de barramento completo + preenchimento do bloco
Leitura de ROM2memória serial mais lenta, não passa pela cache
Escrita em RAM2política write-through: sempre chega à memória

12. Cache L1

A cache existe porque programas reais têm localidade: eles tendem a acessar de novo o que acabaram de acessar (localidade temporal) e a acessar endereços vizinhos (localidade espacial). A cache aposta nisso.

A da IPC-8 é de mapeamento direto: cada endereço de memória só pode ocupar uma linha específica. Isso torna a busca trivial — basta comparar a tag — ao custo de conflitos quando dois endereços muito usados disputam a mesma linha.

ParâmetroValor
Capacidade total32 bytes
Linhas8
Bloco por linha4 bytes
Organizaçãomapeamento direto
Política de escritawrite-through, sem alocação na escrita
Abrangênciasomente RAM (a ROM é acessada diretamente)

Como o endereço é dividido

Com blocos de 4 bytes, os 2 bits menos significativos escolhem o byte dentro do bloco (deslocamento). Os 3 bits seguintes escolhem uma das 8 linhas (índice). O que sobra é a tag, guardada junto com a linha para provar de qual endereço aquele bloco veio.

Calculadora de cacheinforme um endereço
Experimento sugerido

No LAB 04, observe que ler $0040 traz também $0041, $0042 e $0043 para a cache. O acesso seguinte a qualquer um deles custa 1 ciclo em vez de 4 — sem que o programa tenha pedido nada disso.

13. Pilha e sub-rotinas

A pilha ocupa a página $0100–$01FF e cresce para baixo: SP começa em $01FF e é decrementado a cada byte empilhado. Essa convenção — herdada de máquinas reais como o 6502 — deixa a pilha e os dados do programa crescendo em direções opostas, aproveitando melhor a memória livre entre eles.

O que CALL e RET fazem

InstruçãoOperação
CALL endM[SP] ← PCalto; SP−1; M[SP] ← PCbaixo; SP−1; PC ← end
RETSP+1; PCbaixo ← M[SP]; SP+1; PCalto ← M[SP]
PUSHM[SP] ← A; SP ← SP−1
POPSP ← SP+1; A ← M[SP]
Desequilíbrio de pilha

Se uma sub-rotina empilha com PUSH e esquece o POP correspondente, o RET vai desempilhar o dado em vez do endereço de retorno e o PC saltará para um lugar arbitrário. Acompanhe o SP na aba Execução e a região da pilha na aba Memória para diagnosticar isso.

14. Interrupções

Sem interrupções, a CPU só descobre que algo aconteceu se ficar perguntando — é o polling do LAB 01, que queima ciclos sem produzir nada. A interrupção inverte a iniciativa: o dispositivo avisa a CPU.

  1. O dispositivo ativa a linha IRQ.
  2. A CPU termina a instrução em andamento — nunca interrompe pela metade.
  3. Se IE = 1, responde com INTA e empilha PC e FLAGS.
  4. Zera IE, para não ser interrompida dentro do tratamento.
  5. Carrega o PC com o endereço lido do vetor $FFFE–$FFFF.
  6. Executa a ISR e encerra com IRET, que restaura FLAGS, PC e IE.
VetorEndereçoQuando é usado
NMI$FFFAreservado (não mascarável)
RESET$FFFCao ligar ou reiniciar a máquina
IRQ$FFFEpedido mascarável de dispositivo
Transparência

Uma ISR bem escrita preserva tudo o que altera. Como a IPC-8 empilha automaticamente apenas PC e FLAGS, se a sua rotina usar A, ela deve começar com PUSH e terminar com POP — caso contrário o programa interrompido continuará com um acumulador que não é dele.

15. Entrada e saída

A IPC-8 usa E/S mapeada em portas: um espaço de endereçamento separado de 256 posições, acessado exclusivamente por IN e OUT, com o sinal IO/M distinguindo os dois mundos. A alternativa — E/S mapeada em memória, usada por ARM e RISC-V — dispensa instruções especiais, mas consome parte do espaço de endereçamento.

Protocolo do teclado

O controlador mantém um bit de status e um registrador de dado. O programa lê a porta $00, isola o bit 0 e só consome a porta $01 quando há tecla disponível — a leitura do dado limpa o bit de status. Esse é o padrão clássico de handshake por status.

Protocolo do NVMe

Escrever $01 na porta $20 solicita a leitura do setor 0. Cada leitura da porta $21 devolve o byte seguinte do buffer; a porta $22 informa se ainda há dados. É assim que o firmware do LAB 03 traz o bootloader para a memória.

16. Inicialização e códigos POST

Quando a máquina é ligada, a memória RAM contém lixo e a CPU não sabe o que fazer. O único ponto fixo é o vetor de reset: a CPU lê os dois bytes em $FFFC e desvia para lá. Como essa região é ROM, sempre há código válido esperando.

  1. Vetor de reset — PC ← M[$FFFC:$FFFD], apontando para o firmware.
  2. POST — o firmware publica códigos de progresso na porta $80, que aparecem no display de diagnóstico da placa.
  3. Teste de memória — grava e relê um padrão conhecido para confirmar que a RAM responde.
  4. Enumeração de dispositivos — identifica o que está conectado.
  5. Leitura do setor 0 — copia o setor de boot do NVMe para $7C00, byte a byte, pelas portas do controlador.
  6. Entrega de controle — JMP $7C00. A partir daqui, quem manda é o código que veio do disco.
Por que $7C00?

O endereço é uma homenagem: é exatamente onde o BIOS dos PCs compatíveis carrega o setor de boot desde 1981. A escolha original deixava espaço abaixo para a pilha e as estruturas do BIOS, e permaneceu por compatibilidade décadas afora.

17. Von Neumann × Harvard

Von Neumann

Um único espaço de endereçamento e um único barramento para instruções e dados. Simples, flexível e barato — permite carregar programas como se fossem dados, o que é a base de qualquer sistema operacional. Em troca, sofre com o gargalo de acesso único.

Harvard

Memórias e barramentos separados para código e dados, permitindo buscar instrução e operando simultaneamente. Comum em microcontroladores e DSPs, onde o código é fixo na fábrica.

Processadores modernos são, na prática, híbridos: usam um espaço de endereçamento único (Von Neumann) do ponto de vista do programador, mas caches L1 separadas para instruções e dados (Harvard) do ponto de vista do hardware. A IPC-8 é deliberadamente Von Neumann pura, com cache unificada, porque isso torna o gargalo — e a razão de existir da cache — visíveis.

18. Limitações conscientes do modelo

Um simulador didático honesto precisa declarar o que não modela. Nada nesta lista é um defeito: são simplificações escolhidas para manter o conjunto compreensível.

Não modeladoComo é na realidade
PipelineCPUs reais sobrepõem as fases de várias instruções, iniciando uma antes de a anterior terminar — com todos os riscos de dados e de controle que isso acarreta.
Execução fora de ordem e superescalarInstruções são reordenadas e despachadas em paralelo para múltiplas unidades funcionais.
Previsão de desvioPreditores estimam o resultado de um desvio antes de ele ser resolvido; um erro custa dezenas de ciclos.
Hierarquia completa de cacheL1 dividida em instruções e dados, L2 por núcleo, L3 compartilhada, além de associatividade por conjuntos e políticas de substituição.
MMU e memória virtualTradução de endereços, tabelas de páginas, TLB e proteção entre processos.
Múltiplos núcleos e coerênciaVários núcleos compartilhando memória exigem protocolos de coerência de cache.
DMAControladores que transferem dados sem passar pela CPU — no LAB 03, o firmware copia o setor byte a byte justamente para tornar o processo visível.
Barramentos seriais reaisPCI Express, DDR e NVMe usam sinalização diferencial, filas de comandos e protocolos por pacote, não os ciclos paralelos simples aqui representados.
Temporização físicaLatências de DRAM (CAS, RAS), atraso de propagação e integridade de sinal.

19. Glossário

Acumulador
Registrador que serve simultaneamente de operando e destino na maioria das operações aritméticas.
ALU
Arithmetic Logic Unit: circuito combinacional que executa as operações aritméticas e lógicas.
Alta impedância
Estado em que um dispositivo desconecta eletricamente suas saídas do barramento, permitindo que outro o utilize.
Barramento
Conjunto de condutores compartilhados por vários dispositivos para troca de sinais.
CPI
Cycles Per Instruction: média de ciclos de clock consumidos por instrução. Quanto menor, mais eficiente a execução.
Endianness
Ordem em que os bytes de um valor multibyte são armazenados. A IPC-8 é little-endian: byte menos significativo primeiro.
Firmware
Programa gravado em memória não volátil, executado antes de qualquer sistema operacional.
Flag
Bit de estado que descreve uma característica do último resultado da ALU.
ISR
Interrupt Service Routine: rotina executada em resposta a uma interrupção.
Localidade
Tendência de um programa a acessar repetidamente os mesmos endereços (temporal) ou endereços próximos (espacial).
Opcode
Byte que identifica qual operação a CPU deve executar.
Polling
Estratégia em que o programa consulta repetidamente o status de um dispositivo em vez de ser avisado por ele.
POST
Power-On Self-Test: sequência de verificações executada pelo firmware ao ligar a máquina.
RTL
Register Transfer Language: notação que descreve operações como transferências entre registradores.
Tag
Parte alta do endereço guardada junto a uma linha de cache para identificar de onde veio o bloco.
Vetor de interrupção
Posição fixa de memória que contém o endereço da rotina a executar em determinado evento.
Write-through
Política em que toda escrita atualiza a cache e a memória principal simultaneamente.

20. Referências e leituras

Os conceitos representados aqui seguem a literatura clássica de organização e arquitetura de computadores. Para aprofundamento:

  • Patterson & Hennessy — Organização e Projeto de Computadores: a Interface Hardware/Software. Referência para ciclo de instrução, hierarquia de memória e avaliação de desempenho.
  • Andrew S. Tanenbaum — Organização Estruturada de Computadores. Excelente para a noção de níveis de abstração e microarquitetura.
  • William Stallings — Arquitetura e Organização de Computadores. Cobertura detalhada de barramentos, E/S e interrupções.
  • Charles Petzold — Code: The Hidden Language of Computer Hardware and Software. Constrói um computador do relé ao processador, em linguagem acessível.
  • Nisan & Schocken — The Elements of Computing Systems (projeto Nand2Tetris). Percurso completo de portas lógicas a sistema operacional.

A IPC-8 não reproduz nenhum processador comercial específico. Algumas convenções — pilha descendente na página 1, endereço de boot $7C00, vetores no topo da memória — foram tomadas emprestadas de máquinas históricas por seu valor pedagógico e de reconhecimento.