No artigo anterior — CPU — Componentes e Ciclo de Instrução — apresentamos os blocos que formam a CPU: UAL, UC, registradores, decodificador e clock. Descrevemos os microeventos do ciclo de busca em notação LTR e vimos como o CI, o REM e o RI cooperam para trazer uma instrução da memória. Mas descrevemos tudo em termos gerais. Agora vamos concreto: vamos acompanhar um processador hipotético executando instruções reais, bit a bit.
Usar um processador simplificado como modelo pedagógico é uma estratégia clássica na área: eliminamos a complexidade de arquiteturas comerciais (x86, ARM) e nos concentramos nos mecanismos fundamentais que qualquer processador real compartilha.
Neste artigo você vai entender:
- a organização do processador hipotético de 12 bits;
- o conjunto completo de instruções e sua notação em LTR;
- como codificar uma instrução em binário e hexadecimal;
- o fluxograma do ciclo de instrução completo;
- a execução passo a passo de LDA e ADD com tabelas de estado;
- os fundamentos da linguagem de montagem (assembly);
- programas assembly completos para problemas práticos.
O processador hipotético #
Apesar de toda essa complexidade física dos chips modernos, os fundamentos lógicos que operam lá dentro permanecem surpreendentemente parecidos com os de seus ancestrais. Para entendermos como a CPU busca e executa instruções sem a “poluição” de bilhões de transistores e pipelines complexos, vamos dar um passo atrás. Usaremos como base um modelo de computador hipotético de apenas 12 bits.
O processador hipotético tem uma organização enxuta que mantém todos os componentes essenciais de um processador real. Sua especificação completa:
| Componente | Tamanho | Justificativa |
|---|---|---|
| Palavra | 12 bits | Tamanho de todas as células de memória |
| Endereços | 8 bits | \(2^8 = 256\) células endereçáveis |
| Células de memória | 12 bits | Uma instrução ou dado por célula |
| ACC (Acumulador) | 12 bits | Mesmo tamanho da palavra |
| CI / PC | 8 bits | Basta endereçar as 256 células |
| REM / MAR | 8 bits | Mesmo tamanho dos endereços |
| RDM / MBR | 12 bits | Mesmo tamanho da palavra |
| RI / IR | 12 bits | Armazena instrução completa |
Perceba a coerência: o CI tem 8 bits porque 8 bits bastam para endereçar 256 células; o REM também tem 8 bits porque ele precisa transportar endereços; o RDM, o RI e o ACC têm 12 bits porque trabalham com palavras completas.
Formato das instruções #
Cada instrução ocupa exatamente uma célula de memória — 12 bits divididos em dois campos:
$$\underbrace{b_{11}\ b_{10}\ b_9\ b_8}_{\text{C.Op (4 bits)}} \quad \underbrace{b_7\ b_6\ b_5\ b_4\ b_3\ b_2\ b_1\ b_0}_{\text{Operando (8 bits)}}$$- 4 bits de C.Op → \(2^4 = 16\) operações distintas possíveis
- 8 bits de operando → \(2^8 = 256\) endereços, cobrindo toda a memória
O número de operações possíveis e o espaço de endereçamento crescem exponencialmente com os bits disponíveis. Adicionar 1 bit ao C.Op dobra o número de instruções; adicionar 1 bit ao operando dobra o espaço de memória endereçável.
Exemplo — Dimensionando um conjunto de instruções
Um processador tem 128 instruções distintas e memória com 512 palavras. Quantos bits são necessários para o C.Op e para o operando? Qual o tamanho total da instrução?
C.Op: \(\log_2 128 = \log_2 2^7 = \mathbf{7\ \text{bits}}\)
Operando: \(\log_2 512 = \log_2 2^9 = \mathbf{9\ \text{bits}}\)
Instrução = \(7 + 9 = \mathbf{16\ \text{bits}}\)
Registradores: CI e REM → 9 bits (endereçam memória); RDM e RI → 16 bits (armazenam palavras). Capacidade total: \(512 \times 16 = 8192\ \text{bits} = > 1\ \text{Kbyte}\).
Efeito de aumentar 1 bit no C.Op
Se esse processador passasse de 16 para 17 bits por instrução (mantendo o operando com 9 bits), o C.Op teria \(17 - 9 = 8\) bits → 256 operações possíveis. Um único bit a mais dobra o repertório de instruções.
O conjunto de instruções #
O processador hipotético tem 15 instruções, cobrindo operações aritméticas, de movimentação de dados, desvios condicionais e incondicionais, e E/S:
| C.Op (hex) | Mnemônico | Operação em LTR | Descrição |
|---|---|---|---|
| 0 | HLT | — | Parar execução |
| 1 | LDA Op | \(\text{ACC} \leftarrow (Op)\) | Carregar da memória para o ACC |
| 2 | STR Op | \((Op) \leftarrow \text{ACC}\) | Armazenar ACC na memória |
| 3 | ADD Op | \(\text{ACC} \leftarrow \text{ACC} + (Op)\) | Somar |
| 4 | SUB Op | \(\text{ACC} \leftarrow \text{ACC} - (Op)\) | Subtrair |
| 5 | JZ Op | Se \(\text{ACC} = 0\): \(\text{CI} \leftarrow Op\) | Desvio se zero |
| 6 | JP Op | Se \(\text{ACC} > 0\): \(\text{CI} \leftarrow Op\) | Desvio se positivo |
| 7 | JN Op | Se \(\text{ACC} < 0\): \(\text{CI} \leftarrow Op\) | Desvio se negativo |
| 8 | JMP Op | \(\text{CI} \leftarrow Op\) | Desvio incondicional |
| 9 | GET Op | Entrada \(\rightarrow (Op)\) | Ler da porta de entrada |
| A | PRT Op | \((Op) \rightarrow\) saída | Imprimir/enviar para saída |
| B | MPY Op | \(\text{ACC} \leftarrow \text{ACC} \times (Op)\) | Multiplicar |
| C | DIV Op | \(\text{ACC} \leftarrow \text{ACC} \div (Op)\) | Dividir |
| D | INC | \(\text{ACC} \leftarrow \text{ACC} + 1\) | Incrementar ACC |
| E | DCR | \(\text{ACC} \leftarrow \text{ACC} - 1\) | Decrementar ACC |
O código F permanece livre para futuras extensões ou reservado.
Costumamos nos referir ao conjunto de instruções como ISA (Instruction Set Architecture). Ele define a interface entre o software e o hardware: quais operações o processador pode realizar e como elas são codificadas.
As instruções de desvio condicional (JZ, JP, JN) alteram o CI somente se a condição for verdadeira. Caso contrário, a execução continua normalmente — o CI já foi incrementado no ciclo de busca, portanto a próxima instrução sequencial é executada automaticamente.
Codificando instruções #
Para codificar uma instrução em hexadecimal, basta concatenar os bits do C.Op com os bits do operando:
LDA 180\(_{10}\):
- C.Op de LDA: \(1_{10} = 0001_2\)
- Endereço do operando: \(180_{10} = 1011\,0100_2 = \text{B4}_{16}\)
- Instrução completa (12 bits): \(\underbrace{0001}_{\text{C.Op}} \underbrace{10110100}_{\text{operando}} = \mathbf{1\text{B}4}_{16}\)
ADD 181\(_{10}\):
- C.Op de ADD: \(3_{10} = 0011_2\)
- Endereço do operando: \(181_{10} = 1011\,0101_2 = \text{B5}_{16}\)
- Instrução completa: \(\underbrace{0011}_{\text{C.Op}} \underbrace{10110101}_{\text{operando}} = \mathbf{3\text{B}5}_{16}\)
O processo inverso — decodificar uma instrução hexadecimal — é igualmente direto: basta separar os 4 bits mais significativos (C.Op) dos 8 bits menos significativos (operando):
Exemplo — Decodificando \(\text{135}_{16}\)
\(\text{135}_{16} = 0001\ 0011\ 0101_2\)
C.Op = \(0001_2 = 1_{10}\) → LDA
Operando = \(0011\ 0101_2 = \text{35}_{16} = 53_{10}\) → endereço 53
Instrução decodificada: LDA 53
O ciclo de instrução completo #
Com o conjunto de instruções definido, o fluxograma do ciclo de instrução fica completo. Ele opera indefinidamente até encontrar HLT:
flowchart TD
START(["▶ INÍCIO"])
subgraph BUSCA["Ciclo de Busca"]
B1["REM ← CI
Envia endereço ao barramento"]
B2["RDM ← M(REM)
Lê instrução da MP"]
B3["RI ← RDM
CI ← CI + 1"]
end
subgraph EXEC["Ciclo de Execução"]
E1{"Decodificar
C.Op de RI"}
E2{"Precisa
buscar operando?"}
E3["REM ← operando de RI
RDM ← M(REM)"]
E4["Executar operação
(UAL ou UC)"]
end
HLT{"HLT?"}
STOP(["⏹ PARAR"])
START --> B1
B1 --> B2
B2 --> B3
B3 --> E1
E1 --> E2
E2 -->|"Sim"| E3
E3 --> E4
E2 -->|"Não"| E4
E4 --> HLT
HLT -->|"Não"| B1
HLT -->|"Sim"| STOP
Note que o CI é incrementado no ciclo de busca, antes da execução. Quando a instrução atual está sendo executada, o CI já aponta para a próxima. Isso é importante para as instruções de desvio: JMP e as variantes condicionais sobrescrevem o CI durante a execução, redirecionando o fluxo do programa.
Execução passo a passo — LDA #
Vamos acompanhar a execução de LDA 1B4₁₆ com o estado inicial: CI = 02;
MP[02] = 1B4₁₆ (a instrução); MP[B4] = 1A7₁₆ (o dado a carregar).
| Passo | Operação em LTR | Estado dos registradores |
|---|---|---|
| 1 | \(\text{REM} \leftarrow (\text{CI})\) | REM = 02 |
| 2 | \(\text{RDM} \leftarrow M(\text{REM})\) | RDM = 1B4 |
| 3 | \(\text{RI} \leftarrow \text{RDM}\) | RI = 1B4 |
| 4 | \(\text{CI} \leftarrow \text{CI} + 1\) | CI = 03 |
| 5 | Decodificação: 4 MSBs de 1B4 = 0001 → LDA | — |
| 6 | Operando B4 → REM | REM = B4 |
| 7 | UC ativa READ no barramento de controle | — |
| 8 | \(\text{RDM} \leftarrow M(\text{B4})\) | RDM = 1A7 |
| 9 | \(\text{ACC} \leftarrow \text{RDM}\) | ACC = 1A7 ✓ |
Os passos 1–4 são o ciclo de busca (os mesmos \(t_0, t_1, t_2\) do artigo anterior). Os passos 5–9 são o ciclo de execução específico do LDA.
Execução passo a passo — ADD #
Continuando a partir do estado deixado pelo LDA: CI = 03; MP[03] = 3B5₁₆; ACC = 1A7₁₆; MP[B5] = 07D₁₆.
| Passo | Operação em LTR | Estado dos registradores |
|---|---|---|
| 1 | \(\text{REM} \leftarrow (\text{CI})\) | REM = 03 |
| 2 | \(\text{RDM} \leftarrow M(\text{REM})\) | RDM = 3B5 |
| 3 | \(\text{RI} \leftarrow \text{RDM}\) | RI = 3B5 |
| 4 | \(\text{CI} \leftarrow \text{CI} + 1\) | CI = 04 |
| 5 | Decodificação: 4 MSBs de 3B5 = 0011 → ADD | — |
| 6 | Operando B5 → REM | REM = B5 |
| 7 | UC ativa READ | — |
| 8 | \(\text{RDM} \leftarrow M(\text{B5})\) | RDM = 07D |
| 9 | UAL recebe ACC = 1A7 e RDM = 07D | — |
| 10 | UAL calcula: \(\text{1A7}_{16} + \text{07D}_{16}\) | — |
| 11 | \(\text{ACC} \leftarrow \text{resultado}\) | ACC = 224 ✓ |
Verificação: \(\text{1A7}_{16} = 423_{10}\); \(\text{07D}_{16} = 125_{10}\); \(423 + 125 = 548_{10} = \text{224}_{16}\) ✓
Executando desvios — JMP e JZ #
Os desvios diferem de LDA e ADD em um aspecto importante: em vez de buscar um
dado para a UAL processar, eles alteram o fluxo de execução por meio do
Contador de Instrução.
JMP 009 (desvio incondicional):
- Busca normal → RI recebe a instrução JMP; CI é incrementado.
- Decodificação: UC identifica JMP → sinaliza salto incondicional.
- \(\text{CI} \leftarrow 009\) — o operando vai direto para o CI, sem acesso à MP.
- A próxima busca ocorre no endereço 009.
JZ 007 (desvio se ACC = 0):
- Busca normal → RI = JZ 007; CI é incrementado.
- Decodificação: UC identifica JZ → sinaliza salto condicional.
- A UAL verifica se ACC = 0.
- Se ACC = 0: \(\text{CI} \leftarrow 007\) → próxima execução no endereço 007.
- Se ACC ≠ 0: CI permanece incrementado → próxima instrução sequencial.
A mesma lógica se aplica a JP (desvio se ACC > 0) e JN (desvio se ACC < 0): a condição é avaliada pela UAL usando as flags de estado, e o CI só é sobrescrito se a condição for verdadeira.
Sobre flags neste processador hipotético
Em CPUs reais, desvios condicionais costumam depender de flags de estado
produzidas pela UAL, como Zero, Negative, Carry e Overflow.
Já falamos sobre flags neste artigo.
Neste processador didático, porém, os desvios JZ, JP e JN podem ser
entendidos de forma mais simples: eles testam diretamente o valor lógico do
acumulador (ACC = 0, ACC > 0, ACC < 0).
Da linguagem de máquina ao assembly #
Programar diretamente em hexadecimal é trabalhoso e propenso a erros. A linguagem de montagem (assembly) resolve isso substituindo os códigos binários por mnemônicos alfanuméricos que mantêm uma relação direta com as instruções de máquina.
| Aspecto | Detalhes |
|---|---|
| Relação com a máquina | 1:1 — uma instrução assembly = uma instrução de máquina |
| Legibilidade | Muito maior que código hexadecimal |
| Tradução | Realizada por um programa Montador (Assembler) |
| Portabilidade | Baixa — específica para cada arquitetura |
Compilador vs. Montador
- Montador (Assembler): traduz linguagem assembly para código de máquina da arquitetura alvo, normalmente preservando uma correspondência muito próxima com as instruções reais do processador.
- Compilador: traduz uma linguagem de mais alto nível para alguma forma de representação executável ou intermediária, que depois poderá ser convertida em código de máquina.
Em modelos didáticos como este, é comum tratar assembly como tendo relação quase direta com as instruções da máquina. Em ferramentas reais, porém, pseudoinstruções, macros e otimizações podem quebrar uma correspondência estritamente 1:1.
Estrutura de uma linha assembly #
Rótulo Operação Operandos ; Comentário
INICIO: LDA A ; Carrega valor de A no ACCO rótulo é opcional e identifica o endereço da instrução (útil para desvios). A operação é o mnemônico. O comentário é ignorado pelo montador.
Exemplo: \(X = A + B - C\) #
Em alto nível, uma linha. Em assembly, quatro instruções — uma por operação primitiva da CPU:
LDA A ; ACC ← (A)
ADD B ; ACC ← ACC + (B)
SUB C ; ACC ← ACC − (C)
STR X ; (X) ← ACCCada linha corresponde exatamente a uma instrução de máquina. O compilador, ao processar a expressão de alto nível, gera uma sequência semelhante a essa.
Assembly na prática #
A seguir, programas completos que ilustram o uso do conjunto de instruções do processador hipotético em problemas reais. Os endereços de memória são expressos em hexadecimal.
Verificação de senha com embaralhamento #
Um sistema armazena a senha de forma embaralhada no endereço 402: o valor
guardado é \(S/2 - (300)\), onde \((300)\) é o conteúdo do endereço 300.
O usuário digita sua tentativa no endereço 120. O programa deve verificar se
a tentativa confere e gravar 1 em 220 (acerto) ou 0 (erro).
Endereços auxiliares: 400 = 0, 401 = 1, 403 = 2.
; Estratégia: embaralhar o que o usuário digitou e comparar com o armazenado
000: LDA 120 ; ACC ← tentativa do usuário
001: DIV 403 ; ACC ← ACC / 2
002: SUB 300 ; ACC ← ACC − (300)
003: SUB 402 ; ACC ← (embaralhado calculado) − (embaralhado armazenado) compara com a senha embaralhada armazenada
004: JZ 008 ; Se ACC = 0 → senhas conferem; pula para 008
005: LDA 400 ; ACC ← 0
006: STR 220 ; (220) ← 0 (ACC ≠ 0: senha errada, grava erro)
007: HLT
008: LDA 401 ; ACC ← 1
009: STR 220 ; (220) ← 1 (senha correta, grava acerto)
00A: HLTO padrão SUB → JZ/JP/JN é a forma de implementar uma comparação no processador
hipotético: subtrair os dois valores e verificar se o resultado é zero, positivo
ou negativo.
Folha de pagamento com teto salarial #
Calcular o ganho total de um funcionário:
$$\text{Ganho\_Total} = \min(\text{Ganho\_Bruto} + \text{Bônus},\ \text{Teto}) + \text{Ganho\_Adicional}$$Dados: 15 = Ganho_Bruto, 16 = Bônus, 17 = Teto, 18 = Ganho_Adicional, 19 = Ganho_Total.
00: LDA 15 ; ACC ← Ganho_Bruto
01: ADD 16 ; ACC ← Bruto + Bônus
02: SUB 17 ; ACC ← (Bruto + Bônus) − Teto
03: JP 07 ; Se ACC > 0 (excedeu o teto) → pula para 07
04: LDA 15 ; Não excedeu: refaz Ganho_Bruto
05: ADD 16 ; ACC ← Bruto + Bônus
06: JMP 08 ; Pula para somar adicional
07: LDA 17 ; Excedeu: usa o Teto como base
08: ADD 18 ; ACC ← base + Ganho_Adicional
09: STR 19 ; Ganho_Total ← ACC
0A: HLTMédia de quatro sensores #
Quatro leituras de sensores estão nos endereços 15, 16, 17 e 18.
Calcular a média e armazenar em 13. O endereço 14 contém o valor 2.
; Divisão por 4 = dois DIVs por 2 consecutivos
00: LDA 15 ; ACC ← sensor1
01: ADD 16 ; ACC ← ACC + sensor2
02: ADD 17 ; ACC ← ACC + sensor3
03: ADD 18 ; ACC ← ACC + sensor4 (soma total)
04: DIV 14 ; ACC ← ACC / 2
05: DIV 14 ; ACC ← ACC / 2 (total: dividido por 4)
06: STR 13 ; média ← ACC
07: HLTNeste ISA estendido, DIV é uma instrução explícita. Em uma CPU real, dividir
por 4 também pode ser implementado por deslocamentos de bits, mas isso é um
detalhe de implementação da UAL, não uma exigência do programa assembly.
Dividir por 4 equivale a dois deslocamentos aritméticos de 1 bit à direita —
o mesmo que >> 2 em linguagens de programação modernas.
Média e contagem de valores críticos #
Três medições nos endereços 30, 31 e 32. (a) Calcular a média e
armazenar em 40. (b) Contar quantas medições superam 50 e armazenar em 41.
Endereços auxiliares: 50 = 0, 51 = 1, 53 = 3, 55 = valor crítico 50.
; --- Parte A: Média ---
00: LDA 30 ; ACC ← med1
01: ADD 31 ; ACC ← ACC + med2
02: ADD 32 ; ACC ← ACC + med3
03: DIV 53 ; ACC ← ACC / 3
04: STR 40 ; média ← ACC
; --- Parte B: Contagem de valores > 50 ---
05: LDA 50 ; ACC ← 0 (inicializa contador)
06: STR 41 ; contador ← 0
; --- Testa med1 > 50 ---
07: LDA 30
08: SUB 55 ; ACC ← med1 − 50
09: JN 0E ; se med1 < 50, não conta
0A: JZ 0E ; se med1 = 50, também não conta
0B: LDA 41
0C: ADD 51
0D: STR 41
; --- Testa med2 > 50 ---
0E: LDA 31
0F: SUB 55
10: JN 15
11: JZ 15
12: LDA 41
13: ADD 51
14: STR 41
; --- Testa med3 > 50 ---
15: LDA 32
16: SUB 55
17: JN 1C
18: JZ 1C
19: LDA 41
1A: ADD 51
1B: STR 41
1C: HLTO padrão correto para testar “maior que” com esse processador é:
- subtrair o limiar;
- descartar o caso negativo com JN;
- descartar o caso igual com JZ;
- só então incrementar o contador.
O caminho inverso: STR (Store) #
Enquanto as instruções LDA e ADD trazem dados da memória para a CPU, a
instrução STR faz o exato oposto: salva o resultado do Acumulador de volta na
Memória Principal. O fluxo de microeventos fecha o ciclo de comunicação:
(REM) <- (RI[endereço]): O endereço de destino (onde o dado será salvo) é copiado para o REM.(RDM) <- (ACC): O dado já calculado sai do Acumulador e vai para o RDM (a “sala de espera” da saída).(MP(REM)) <- (RDM): A Unidade de Controle emite o sinal de escrita pelo barramento de controle, e a memória grava o dado no endereço especificado fisicamente.
Esse fluxo fecha o ciclo completo de comunicação entre CPU e memória: buscar, processar e armazenar o resultado.
Por dentro da UAL: Como o silício calcula? #
Até esse ponto, tratamos a operação ADD sem muitos detalhes. O decodificador
manda um sinal e a UAL simplesmente “soma” os valores que chegaram da memória.
Mas como um pedaço de silício consegue resolver matemática?
A resposta é que a UAL não entende números; ela entende eletricidade. Ela é construída por milhares de interruptores microscópicos organizados em circuitos chamados portas lógicas (como AND, OR, NOT e XOR). Cada porta recebe sinais elétricos (zeros e uns) e emite uma resposta baseada em uma regra lógica simples. Caso tenha um pouco de dificuldade, recomendo nosso artigo sobre lógica de programação.
Para realizar a soma de verdade quando a instrução ADD é executada, a CPU
combina essas portas lógicas em blocos matemáticos:
- Meio Somador (Half-Adder): Um circuito simples que usa portas lógicas para somar dois bits individuais, gerando um resultado e um “vai-um” (carry). Seu defeito é não conseguir receber um “vai-um” de uma operação anterior.
- Somador Completo (Full-Adder): A evolução do circuito, capaz de somar três bits (os dois operandos mais o “vai-um” da coluna vizinha).
Ao enfileirar vários Somadores Completos lado a lado, a UAL consegue somar palavras inteiras de 12, 32 ou 64 bits em uma fração de nanossegundo, propagando o “vai-um” do bit menos significativo até o final. É assim que o comando abstrato do Assembly vira um fluxo elétrico real.
Deslocamentos de bits #
Além de usar desvios para otimizar o fluxo do programa, a CPU também possui “atalhos” implementados diretamente no hardware para acelerar a matemática pesada. Em vez de acionar os somadores múltiplas vezes para fazer multiplicações ou divisões simples, a UAL inclui operações de deslocamento (shift). Elas são equivalentes a multiplicar ou dividir por potências de 2, mas executadas quase instantaneamente ao “empurrar” os bits para os lados:
$$\text{Shift left}\ n\ \text{bits} = \times\ 2^n \qquad \text{Shift right}\ n\ \text{bits} = \div\ 2^n$$Já abordamos isso anteriormente em um artigo sobre operadores bitwise, que explorou as operações bit a bit. Vamos ver um exemplo prático para fixar a ideia.
Para \(5_{10} = 0101_2\):
| Operação | Resultado binário | Resultado decimal |
|---|---|---|
| Shift left 1 bit | \(1010_2\) | \(10_{10}\) (\(5 \times 2\)) ✓ |
| Shift right 1 bit | \(0010_2\) | \(2_{10}\) (\(5 \div 2\), truncado) ✓ |
O exemplo da média de sensores (dividir a soma por 4 com dois DIV 14 onde
(14) = 2) é exatamente dois shifts right consecutivos.
Escopo desta observação
O exemplo acima descreve um mecanismo comum em UALs reais. Ele não significa
automaticamente que o processador hipotético deste artigo possua instruções
explícitas de SHL ou SHR no seu repertório assembly.
O Rastreamento de Execução (Tracer) #
Para visualizar o comportamento da CPU ao longo do tempo, é útil montar uma tabela de rastreamento que registre o estado dos principais registradores a cada fase de busca e execução.
A tabela abaixo é uma construção didática, inspirada no funcionamento do
processador hipotético, para acompanhar a sequência LDA 20, ADD 21, STR 22
assumindo MP[20] = 5 e MP[21] = 3:
| Passo | Fase | CI (PC) | REM | RDM | RI | ACC |
|---|---|---|---|---|---|---|
| 1 | Busca | 01 | 00 | LDA 20 |
LDA 20 |
0 |
| 2 | Execução | 01 | 20 | 5 | LDA 20 |
5 |
| 3 | Busca | 02 | 01 | ADD 21 |
ADD 21 |
5 |
| 4 | Execução | 02 | 21 | 3 | ADD 21 |
8 |
| 5 | Busca | 03 | 02 | STR 22 |
STR 22 |
8 |
| 6 | Execução | 03 | 22 | 8 | STR 22 |
8 |
Esse tipo de tabela funciona como um “raio-x” do ciclo de instrução.
Observe o fluxo perfeito: no passo 6, o valor 8, que estava no Acumulador, foi
jogado para o RDM para ser fisicamente gravado no endereço 22 da memória. A
CPU funciona no ritmo do relógio.
Conclusão e próximos artigos #
O processador hipotético condensa os mecanismos essenciais de qualquer processador real: um repertório de instruções codificado em bits, um ciclo que busca e executa cada instrução em sequência, e desvios que alteram esse fluxo com base em condições. O assembly revela a correspondência direta entre essas instruções e o código que o hardware executa.
No próximo artigo, vamos avançar para a execução paralela de múltiplas instruções com a técnica de pipeline. Veremos como isso multiplica o desempenho, quais hazards podem interromper esse fluxo e como a unidade de controle coordena tudo para manter a execução fluida.
Até lá!