Capítulo TRÊS Componentes do computador e modelo de von

Propaganda
Capítulo
TRÊS
Componentes do computador e modelo de von Neumann
3 . 1 Breve histórico
Uma das mais importantes investidas na área computacional, e que merece registro histórico,
foi a do inglês Charles Babbage. Ele projetou dois computadores: Difference Engine
(denominado a seguir “Dispositivo Diferencial”), iniciado em 1823, e o Analytical Engine
(“Dispositivo Analítico”), concebido em 1834, tendo ambos representado grandes avanços
científicos em sua época, embora nenhuma deles tenha sido concluído. O objetivo do
Dispositivo Diferencial era o cômputo automático de tabelas matemáticas. Sua única operação
era a adição, mas a máquina podia resolver grande número de funções úteis pela técnica de
diferenças finitas. Esta máquina foi projetada para polinômios de grau 6 e números binários
de 20 dígitos, mas não foi concluída devido a problemas de inadequação da tecnologia
mecânica disponível. Outra tentativa de Babbage, foi a construção do Dispositivo Analítico,
que deveria realizar qualquer operação matemática automaticamente. Esta máquina já tinha
módulos de armazenamento (memória) e uma unidade operadora (realizando 4 operações
aritméticas). A entrada e saída de dados era feita através de cartões perfurados. Esta máquina
permitia a alteração da seqüência dos comandos executados, dependendo do resultado de
testes realizados. Novamente por problemas técnicos, a construção desta máquina não
chegou ao final. Na tabela a seguir estão reunidas algumas das principais tentativas de valor
histórico no âmbito computacional.
Data
1642
Inventor:máquina
Pascal
1671
Leibnitz
1827
Babbage:
Difference Engine
Babbage:
Analytical Engine
Zuse: Z3
1834
1941
1944
Aiken:
Harward Mark I
Capacidade
adição, subtração
Inovações técnicas
transferência automática de vai-um;
representação em complemento
adição, subtração,
mecanismo para multiplicação
multipl., divisão
e divisão
avaliação polinomial
operação automática
por diferenças finitas
com diversos passos
computador de
mecanismo automático de controle
propósitos gerais
de sequência (programa)
computador de
primeiros computadores de
propósitos gerais
propósitos gerais operacionais
computador de
primeiros computadores de
propósitos gerais
propósitos gerais operacionais
Tabela 3.1 - Principais avanços na computação
Uma das primeiras tentativas para construção de computadores eletrônicos foi feita por volta
de 1930 por John Atanasoff, na Universidade Estadual de Iowa. Era uma máquina
construída com base em válvulas para resolução de equações lineares.
O primeiro computador eletrônico de propósitos gerais foi provavelmente o ENIAC
(Eletronic Numerical Integrator and Calculator), construído entre 1943 e 1946, na
Universidade da Pensilvânia, sob a coordenação de J. Mauchly e J. P. Eckert. Analogamente
à primeira máquina de Babbage, parte da motivação do ENIAC foi a necessidade de construir
tabelas de forma automática, por interesse do sistema militar americano (tabelas balísticas).
Fisicamente, era uma máquina enorme que pesava 30 toneladas e empregava cerca de 18000
3-1
válvulas. Para se ter uma idéia do tempo de execução nesta máquina, eram necessários cerca
de 3 ms para realização de uma multiplicação de 10 dígitos (decimais), o que se constituiu em
grande avanço para a época. Ele trabalhava preponderantemente com valores decimais e não
binários. Na Figura 3.1 é mostrada a estrutura básica do ENIAC.
Com o avanço da pesquisa e o conseqüente desenvolvimento tecnológico, houve grandes
modificações nos computadores. Basicamente, ao longo do tempo, a tecnologia e os estilos
usados na construção de computadores apresentam pontos comuns, que nos permitem
classificá-los em gerações. Na tabela a seguir, são apresentadas as gerações de computadores
de acordo com sua classificação histórica.
Geração
Tecnologias
Válvulas,
1a
memória
de tubos
(1946 catódicos
54)
Transistores, núcleos
2a
de ferrite, discos
(1955 magnéticos
64)
a
Circuitos
integrados
3
(SSI
e
MSI)
(1965 74)
4a
(1975 ?)
Característica de
hardware
aritmética de
ponto fixo
ponto flutuante
registrador índice
processadores E/S
microprogramação
pipeline
memória cache
Característica de
software
linguagem de
máquina, linguagem
assembler
ling. alto-nível
bibliot. de subrotinas
monitores batch
multiprogramação
multiprocessamento
sistema operacional
memória virtual
Circuitos LSI
memórias
semicondutoras
Exemplo
IAS,
UNIVAC
IBM7094
CDC1604
IBM
S/360;
DEC
PDP-8
Amdahl
470;
Intel 8748
Tabela 3.2 - Gerações de computadores
Atualmente, esta tabela [HAY78] já poderia ser completada com uma quinta geração que
incluiria as máquinas maciçamente paralelas, os circuitos VLSI, as máquinas “data-flow”,
etc, dependendo do parâmetro escolhido para embasar esta evolução.
leitora de
cartões
divisor
multiplicador
impressora e
perf. de cartões
tabelas de
e raiz
quadrada
funções
unidade mestre de
programação
Figura 3.1 - Estrutura básica do ENIAC
3-2
a
c
u
m
u
l.
3 . 2 Princípios básicos
Cada computador tem um conjunto de operações e convenções único para determinar as
posições dos dados com os quais a operação será realizada. Os vários computadores diferem
nas operações específicas que fornecem e nos métodos que eles usam para referenciar dados
que serão manipulados por uma operação. Em geral, uma operação tem a forma
OPERAÇÃO
OPERANDOS
e é denominada de instrução. OPERAÇÃO especifica a função que será desempenhada.
OPERANDOS fornece a maneira de calcular a posição atual dos dados com os quais a
operação será realizada.
Um programa é constituído de uma seqüência pré-determinada de instruções, que deve ser
seguida para que seja atingido o objetivo computacional. Este programa e os dados
correspondentes estão armazenados na memória da máquina; o conjunto de instruções (ou
programa) deve ser interpretado para realização do processamento, isto é, a informação
codificada correspondente às ações e operandos deve ser entendida e então processada.
A memória de um sistema de computador tem a função de armazenar dados e instruções; é
organizada em posições, que podem ser visualizadas como elementos em uma matriz. Cada
elemento tem um endereço. Assim, pode-se falar de uma memória que tenha x posições:
cada posição pode ser referenciada diretamente de acordo com a sua colocação na seqüência.
Por exemplo, se uma memória tem 4096 posições, existem posições de memória 0, 1, 2,
3,...., 4094 e 4095. Quando um destes números aparece nos circuitos de controle
conectados à memória, o conteúdo (o valor que está na posição) será trazido da memória para
os circuitos da unidade de processamento ou a informação na unidade de processamento será
armazenada na memória, dependendo do trabalho associado com o endereço.
Instruções em um computador são executadas em uma seqüência determinada por suas
posições de memória. Na maioria dos computadores (que formam a classe das chamadas
máquinas de von Neumann, cujo modelo básico será visto na seção 3.5), instruções e dados
são distribuídos em posições de memória.
O endereço representa uma posição particular na memória e pode ser formado de várias
maneiras. A representação trivial de um endereço está na parte de uma instrução chamada
campo de endereço. Contudo, há várias maneiras de se modificar um campo de endereço por
valores em outras partes do processador (aritmética de endereços). As diversas
possibilidades e vantagens destas técnicas serão mostradas mais adiante na disciplina.
A unidade lógica e aritmética realiza ações indicadas nas instruções, executando operações
numéricas (aritméticas) e não numéricas (lógicas) além da preparação de informações para
desvios do programa. O controle do programa e a unidade lógica e aritmética formam a
unidade central de processamento (UCP), ou simplesmente processador.
Busca - decodificação - execução de instruções
Um elemento no processador, denominado de contador de instruções ou apontador de
instruções, contém a posição da próxima instrução a ser executada. Quando uma seqüência
de execução de instruções tem início, a instrução cujo endereço está no contador de
instruções é trazida da memória para uma área de armazenamento chamada registrador de
instrução. Este processo consiste na busca de instrução.
A instrução é interpretada por circuitos de decodificação que fazem com que sinais
eletrônicos sejam gerados no processador como resultado do valor do campo de operação,
isto é, decodificam a informação correspondente à operação a ser realizada.
Esses sinais, ou seqüência de sinais, resultam na execução da instrução. Execução é a
aplicação da função do operador nos operandos. Quando a execução de uma instrução é
3-3
terminada, o contador de instruções é atualizado para o endereço de memória da próxima
instrução. Esta instrução é então trazida da memória para o registrador de instruções e
executada, repetindo-se assim o ciclo de busca-decodificação-execução.
A seqüência de instruções pode mudar como resultado de uma instrução que direciona um
desvio (também chamada transferência ou salto). Estas instruções contêm o endereço da
próxima instrução a ser executada ao invés do endereço de um operando. Elas causam
mudanças no fluxo do programa como resultados das condições nos dados. O desvio
condicional representado por uma estrutura de programação de alto nível de IF (teste para
uma condição especificada e alteração do fluxo de programa se a condição é atendida) traduzse em algum tipo de instrução de desvio.
3 . 3 Elementos funcionais básicos
Um computador é composto por blocos convencionalmente chamados de memória, unidades
operacionais, unidades de controle e dispositivos de entrada e saída (Figura 3.2).
A unidade operacional e a unidade de controle tem funcionalidade específica, conforme será
visto na seqüência. Reunidas, entretanto, recebem no seu conjunto a denominação de
unidade central de processamento (UCP) ou processador. Memórias, unidades operacionais,
unidades de controle e dispositivos de entrada e saída são formados por elementos de menor
complexidade, tais como registradores, contadores, multiplexadores, seletores,
decodificadores, somadores e portas lógicas (AND, OR, INVERSOR).
Registradores são elementos digitais com capacidade de armazenar dados. Têm associados a
si sinais de carga, que determinam quando serão armazenados novos conteúdos nestes
elementos; ao ser acionado este sinal (carga), o registrador copia para si o dado que está em
suas linhas de entrada. Contadores, multiplexadores, seletores, decodificadores, somadores
e portas lógicas são elementos com capacidade de operar sobre dados, alterando-os ou
fornecendo um novo dado como resultado da operação que realizam. Elementos digitais
necessitam ser ativados ou habilitados para realizar uma determinada operação. Os sinais
responsáveis pela ativação ou habilitação de componentes digitais são conhecidos como
sinais de controle.
memória
controle
unidade
operacional
entrada/
saída
Figura 3.2 - Elementos básicos de um computador
Dados são transferidos, entre os diversos elementos de um computador, por caminhos
físicos chamados barramentos. Barramentos são caminhos físicos que permitem o
transporte de dados entre os vários elementos da parte operacional, memória e sistema de
3-4
entrada e saída. Um barramento só pode receber dados de uma fonte de cada vez. Do ponto
de vista de arquitetura, um barramento se caracteriza pela sua largura em bits. A largura em
bits do barramento deve corresponder ao comprimento dos elementos (dados, endereço,
controle) que são por ele transportados.
Cada um dos blocos básicos do computador é comentado, em detalhes, a seguir.
3 . 3 . 1 Memória
A memória é formada por elementos armazenadores de informação. Uma memória está
dividida em palavras. Cada palavra ocupa uma posição de memória e é identificada
univocamente por um endereço. O conteúdo armazenado nas palavras da memória tanto
pode representar dados como instruções. Um esquema da estrutura convencional para a
memória de um computador é mostrado na Figura 3.3.
RDM in
R
E
M
read
memória
write
RDM out
Figura 3.3 - Modelo estrutural da memória
Os registradores mostrados na Figura 3.3 são:
REM :
registrador de endereços da memória - contém o endereço do
dado a ser lido ou escrito na memória.
RDM i n :
registrador de dados da memória (entrada) - contém o dado
a ser escrito na memória.
RDM out :
registrador de dados da memória (saída) - contém o dado
lido da memória.
Os sinais de controle significam:
read:
leitura da memória - o conteúdo da posição de memória
endereçada por REM é copiada em RDMout .
write:
escrita na memória - a posição de memória endereçada por REM
recebe o conteúdo de RDMin .
Uma memória é caracterizada por vários parâmetros. Os mais importantes são: tamanho,
velocidade e tecnologia. No nível de arquitetura, interessam: tamanho da palavra em bits e
tamanho da memória em palavras. Estes tamanhos geralmente são indicados sob a forma de
potências de dois. O tamanho da palavra determina o comprimento em bits do RDM
(registrador de dados) e o tamanho da memória o comprimento em bits do REM (registrador
de endereços).
3-5
3 . 3 . 2 Unidade operacional
A unidade operacional, também chamada de bloco operacional, executa as transformações
sobre dados especificadas pelas instruções de um computador. Compõe-se basicamente de
uma unidade lógica e aritmética, de registradores de uso geral e específico e dos barramentos
que interligam todos esses elementos.
O número, tamanho e uso dos registradores e a quantidade e tipo de operações que a unidade
lógica e aritmética realiza são alguns dos fatores que determinam o porte de um processador.
Unidade lógica e aritmética ( ULA )
A ULA realiza operações aritméticas e operações lógicas sobre um ou mais operandos.
Exemplos de operações realizadas pela ULA: soma de dois operandos; negação de um
operando; inversão de um operando; AND (“E” lógico) de dois operandos; OR (“OU” lógico)
de dois operandos; deslocamento de um operando para a esquerda ou direita ; rotação de um
operando para a esquerda ou direita
As operações da ULA são, geralmente, muito simples. Funções mais complexas, exigidas
pelas instruções da máquina, são realizadas pela ativação seqüencial das várias operações
básicas disponíveis. Um exemplo é a execução de instruções de multiplicação em alguns
computadores, que compreende a ativação de operações sucessivas de soma e deslocamento
na ULA.
A ULA fornece o resultado da operação e também algumas indicações sobre a operação
realizada. Tais indicações são chamadas códigos de condição. Exemplos de alguns
códigos de condição comumente gerados na ULA são:
• Overflow:
(ou estouro de campo) indica que o resultado de uma operação aritmética não
pode ser representado no espaço (tamanho da palavra) disponível.
• Sinal:
indica se o resultado da operação é negativo ou positivo.
• Carry:
dependendo da operação realizada (soma ou subtração) pode representar o bit de
vai-um (carry-out) ou vem-um (borrow-out). Usado muitas vezes também
em operações de deslocamento para guardar ou fornecer o bit deslocado. A
indicação de carry não deve ser confundida com overflow.
• Zero:
indica se o resultado da operação realizada é nulo.
O modelo estrutural da unidade lógica e aritmética é mostrado na Figura 3.4.
operandos
controle
U L A
códigos de
condição
resultado
Figura 3.4 - Modelo estrutural da ULA
3-6
Os sinais de controle que devem ser fornecidos para a ULA servem para selecionar a
operação desejada entre as operações básicas disponíveis. Convém salientar que a ULA não
armazena nem o resultado, nem os operandos, nem os códigos de condição gerados.
Uma ULA se caracteriza por:
• comprimento em bits dos operandos
• número e tipo de operações
• códigos de condição gerados
Acumulador
O acumulador é um registrador e tem por função armazenar um operando e/ou um
resultado fornecido pela ULA. Nos computadores mais simples é encontrado apenas um
acumulador. Em algumas arquiteturas mais complexas vários registradores podem
desempenhar as funções de um acumulador.
Como todos os registradores, o acumulador é ativado por um sinal de controle de carga. A
cada sinal de carga, o dado na entrada do registrador é copiado para o seu interior
(obviamente o antigo conteúdo do acumulador é perdido).
Um acumulador, sendo um registrador, se caracteriza ao nível de arquitetura apenas pelo seu
comprimento em bits.
3 . 3 . 3 Unidade de controle
Para gerenciar o fluxo interno de dados e o instante preciso em que ocorrem as transferências
entre uma unidade e outra são necessários sinais de controle. Esses sinais são fornecidos
por um elemento conhecido por unidade de controle.
Cada sinal de controle comanda uma microoperação. Uma microoperação pode ser
responsável pela realização de uma carga em um registrador, uma seleção de um dado para
entrada em um determinado componente, uma ativação da memória, a seleção de uma
operação da ULA ou a habilitação de um circuito lógico, para citar alguns exemplos.
Unidades de controle são máquinas de estado finitas (FSM) realizadas por lógica seqüencial.
Lógica seqüencial e lógica combinacional são caracterizadas, informalmente, como segue:
• Lógica seqüencial: os sinais de saída são função dos sinais de entrada e do estado
anterior do sistema.
• Lógica combinacional: os sinais de saída são função exclusiva dos sinais de
entrada.
Existem várias formas de implementar lógica seqüencial. Tais formas de implementação
caracterizam a organização da unidade de controle. As duas organizações usuais são:
• Organização convencional: a unidade de controle é composta por componentes
digitais como flip-flops, contadores e decodificadores, que geram, seqüencialmente
e nos instantes de tempo adequados, todos os sinais de controle necessários à
ativação da unidade operacional, do sistema de entrada e saída e da memória.
• Organização microprogramada: em uma unidade de controle microprogramada,
os sinais de controle estão armazenados numa memória especial chamada memória
de controle. Vários sinais de controle são buscados a cada acesso à memória de
controle. Esses sinais estão agrupados em longas palavras chamadas
microinstruções. Um conjunto de microinstruções forma um microprograma.
3-7
A unidade de controle, baseada em sinais de entrada obtidos do registrador de estado (RST)
e do registrador de instruções (RI), gera como saída todos os sinais de controle necessários
para a unidade operacional (Figura 3.5).
O registrador de instruções é um elemento do bloco de controle, o registrador de estado é um
elemento da interface entre a unidade de controle e a unidade operacional. Em função de uma
arquitetura específica, esse último registrador tanto pode aparecer classificado numa unidade
como em outra.
RI
RST
unidade
de
controle
sinais de
controle
Figura 3.5 - Esquema de uma unidade de controle
3 . 3 . 4 Registradores especiais
Existem, no computador, alguns registradores com funções especiais, conforme será
explicado a seguir. Dependendo da arquitetura e da organização de cada máquina, alguns
registradores podem estar posicionados na unidade de controle ou na unidade operacional.
Esta localização, entretanto, no momento não é relevante; aqui será assumida a posição
adotada por cada máquina estudada.
Apontador de instruções
O apontador de instruções é um registrador e tem por função manter atualizado o
endereço de memória da próxima instrução que deve ser executada. Também é chamado de
contador do programa (ou PC, do inglês Program Counter). O nome contador do
programa se deve ao fato de, no modelo básico de um computador, instruções consecutivas
de um programa serem armazenadas em palavras da memória que possuem endereços
também consecutivos. Assim, para acessar a próxima instrução, basta contar mais um.
Do ponto de vista de arquitetura, um apontador de instruções se caracteriza pelo seu
comprimento em bits. Como o PC contém um endereço de memória, o comprimento do PC é
função do tamanho da memória onde estão armazenados os programas em execução.
Registrador de instruções ( RI )
O registrador de instruções armazena a instrução que está sendo executada. Em função
do conteúdo desse registrador, a unidade de controle determina quais os sinais de controle
devem ser gerados para executar as operações determinadas pela instrução. Do ponto de vista
de arquitetura, um registrador de instruções se caracteriza pelo seu comprimento em bits. O
comprimento do RI depende do tamanho e codificação das instruções do computador.
Registrador de estado ( RST )
O registrador de estado armazena códigos de condição gerados pela unidade lógica e
aritmética (e, eventualmente, por outros elementos, como os sinais de interrupção gerados
por dispositivos de entrada e saída). Em função do conteúdo desse registrador, a unidade de
controle toma decisões sobre a geração ou não de certos sinais de controle. Do ponto de vista
3-8
de arquitetura, um registrador de estado se caracteriza pelo seu comprimento em bits, que é
uma função do número de códigos de condição implementados na máquina.
3 . 3 . 5 Conjunto de instruções e modos de endereçamento
Uma instrução é um conjunto de bits devidamente codificados que indica ao computador que
seqüência de microoperações ele deve realizar. Instruções são classificadas por semelhança
de propósito e formato. Classificações comuns incluem, entre outras:
• instruções de transferência de dados
• instruções aritméticas e lógicas
• instruções de teste e desvio
O conjunto de todas as instruções que um determinado computador reconhece e pode
executar é chamado de conjunto de instruções. Qualquer seqüência finita de instruções
de um determinado conjunto de instruções compõe um programa.
Muitas da instruções de um computador realizam operações sobre operandos (p.ex. soma
de dois elementos). Operandos podem estar em qualquer posição da memória ou em
qualquer registrador (inclusive em um registrador pertencente a um dispositivo de entrada e
saída). Para que a unidade de controle saiba onde achar um operando é necessário que o
endereço do operando apareça junto a instrução. Nas instruções de desvio (parecidas
com GOTO e IF-THEN em linguagens de alto nível) é necessário indicar, ao invés de
endereço de operando, para qual posição ou endereço de programa se quer desviar. As
diversas formas em que o endereço de um operando pode aparecer, somadas às diversas
formas em que um endereço de desvio pode ser encontrado em um computador, caracterizam
os modos de endereçamento desse computador.
3 . 3 . 6 Ciclo de busca-decodificação-execução de instruções
Busca, decodificação e execução de instruções são as tarefas básicas realizadas por um
processador. Caracterizam um ciclo, pois as tarefas são executadas repetidamente, sempre e
sempre, até que seja decodificada uma instrução que indique parada ao computador (halt,
stop, wait, etc).
Busca: na fase de busca é lida uma instrução da memória. Essa fase envolve:
• copiar o apontador de programa (PC ) para o registrador de endereços da
memória (REM),
• ler uma instrução da memória,
• copiar o registrador de dados da memória (RDM) para o registrador de
instruções (RI),
• atualizar o apontador de programa (PC ).
Decodificação: nessa fase é determinada qual instrução deve ser executada. A
decodificação geralmente é realizada por lógica combinacional.
Execução: na fase de execução, para cada tipo de instrução é realizado, conforme
necessário:
• cálculo do endereço de operandos,
• busca de operandos da memória,
• seleção de operação da ULA,
• carga de registradores,
• escrita de operandos na memória,
• atualização do PC para desvios.
3-9
O controle de todas as operações do ciclo de busca-decodificação-execução de instruções é
de responsabilidade da unidade de controle. O programador, mesmo o de baixo nível (ou
seja, aquele que conhece a linguagem de máquina de seu computador), não precisa se
preocupar com isso, a não ser para calcular os tempos envolvidos na execução de seu
programa.
3 . 3 . 7 Programação de um processador
A única linguagem que um processador entende e tem condições de executar não é, ao
contrário do que muitos pensam, o inglês, mas sim linguagem de máquina. Linguagem
de máquina é uma imagem numérica (binária) que representa a codificação do conjunto de
instruções de um computador. Todos os programas objeto de um computador estão
representados e armazenados em linguagem de máquina.
Representações numéricas são de difícil manipulação até mesmo por programadores
experientes. Programas em linguagem de máquina são difíceis de elaborar, testar e alterar.
Para facilitar as tarefas de programação e depuração, mnemônicos (em inglês) foram
associados aos códigos das instruções, nomes aos operandos e rótulos (labels) às
posições ocupadas pelo programa. A partir de então, não é mais necessário trabalhar com
códigos numéricos, pois toda a programação de baixo nível é feita usando símbolos.
Um programa escrito com auxílio de símbolos, ou seja em linguagem simbólica, precisa ser
traduzido em linguagem de máquina para que possa ser executado. Essa tradução recebe o
nome de montagem e, quando automatizada, o programa que a realiza recebe o nome de
montador.
Um montador realiza praticamente apenas uma tradução “um para um” das instruções da
linguagem simbólica para instruções de máquina (ao contrário de um compilador, que gera
rotinas em linguagem de máquina para cada instrução da linguagem de alto nível e depois
otimiza código e alocação de variáveis). Montadores modernos, para computadores de 16 e
32 bits por exemplo, são bastante poderosos e confortáveis, aceitando comandos específicos
(chamados comumente de pseudo-instruções) e tipos de dados não disponíveis na
linguagem de máquina.
3 . 4 Um computador de primeira geração: o EDVAC
No ENIAC, e nas máquinas que o antecederam, os programas e os dados eram armazenados
em memórias separadas. O armazenamento inicial de programas e sua alteração constituía-se
em uma atividade extremamente cansativa. A idéia de armazenar programas e dados na
mesma unidade de memória - que corresponde ao conceito de programa armazenado - é
atribuída ao matemático húngaro John von Neumann (1903 – 1957), que atuou como
consultor no projeto do ENIAC. Sua proposta foi publicada em 1945 para um computador
novo, o EDVAC (Electronic Discrete Variable Computer). Além de facilitar o processo de
programação, o conceito de programa armazenado torna possível ao programa modificar
suas próprias instruções.
Além de ser um computador de programa armazenado, o EDVAC trazia outras inovações:
memória de capacidade bastante aumentada (principal 1 com 1024 palavras, implementada
através de uma linha de atraso em mercúrio, e secundária magnética de 20k palavras);
representação interna em binário; e circuitos aritméticos binários seriais, devido à entrada de
dados serial.
A estrutura básica de um computador de primeira geração, que pode ser correspondente a
uma máquina semelhante ao EDVAC, é mostrada na Figura 3.6.
1
A memória principal deve ser rápida: armazena pelo menos o programa em execução e os dados
correspondentes. A memória secundária é mais lenta e serve para armazenar grandes volumes de dados e
programas que não estão em execução.
3-10
unidades de
memória
secundárias
unidade
central de
processamento
memória
principal
unidade
lógicoaritmética
teletipo
unidade de
controle de
programa
leitora de
cartões
impressora e
perfuradora
de cartões
equipamentos de E/S
Figura 3.6 - Arquitetura de um computador de primeira geração
Antes da execução de um programa no EDVAC, todas as instruções e dados eram colocados
na memória principal. Uma instrução aritmética, por exemplo, tinha o seguinte formato:
A1
A2
A3
A4
OP
que significava o seguinte: realize a operação OP com o conteúdo das posições de memória
principal, cujos endereços são A1 e A 2 e coloque o resultado na posição A3. O quarto
endereço, A4, especifica a posição da próxima instrução a ser executada.
Uma instrução condicional tinha o seguinte formato:
A1
A2
A3
A4
C
que significava o seguinte: se o número em A1 não é menor do que o número em A2 então
execute a instrução constante na posição A3, senão, execute a instrução em A4.
Ainda existia um par de instruções de entrada e saída para a transferência de informações
entre as memórias principal e secundária. Nestas instruções, o campo do segundo endereço
era dividido em dois componentes, um modificador de operação m, que indicava a direção da
transferência de dados, e um número n, que representava o endereço do condutor no meio de
armazenamento secundário a ser usado. O formato da instrução era:
A1
m,n
A3
A4
W
significando:
1. Se m = 1, transfira para o condutor n a seqüência de palavras armazenadas na memória
principal nas posições A1, A1+1, A 1+2, ....., A 3.
2. Se m = 2, transfira do condutor n a seqüência de palavras para as posições A1, A 1+1,
A1+2, ....., A 3 na memória principal.
Novamente A4 era o endereço da próxima instrução a ser realizada.
Observe na estrutura do EDVAC, mostrada na Figura 3.6, que há dois conjuntos de linhas
originados na unidade central de processamento que conduzem informações entre esta
unidade e os equipamentos de entrada e saída. O conjunto de linhas que parte do bloco
3-11
denominado, na figura, de unidade de controle de programa conduz informações de
controle aos elementos de E/S, determinando quais atividades devem ser realizadas nestes
elementos (por exemplo, indicando à leitora de cartões que ela deve efetuar a leitura do
próximo cartão, ou indicando à impressora que ela deve imprimir o caracter que se encontra
disponível). O outro conjunto de linhas, que está relacionado ao bloco unidade lógicoaritmética conduz dados que serão ou que foram processados. Assim, este conjunto de
linhas transporta dados provenientes da leitora de cartões, transporta dados para a teletipo e
recebidos da mesma, e assim por diante.
O equipamento de entrada e saída do EDVAC consistia de um dispositivo semelhante a uma
máquina de escrever, que transferia informação diretamente para os condutores magnéticos,
e uma impressora, que revertia este processo. O EDVAC tornou-se operacional em 1951.
Principais inconvenientes do EDVAC
O formato de instrução utilizado no EDVAC, bem como a arquitetura e organização
escolhidas para a sua implementação, resultam em problemas, tais como os explicados a
seguir.
Considere o formato de uma instrução aritmética, por exemplo, de uma soma: tem-se quatro
operandos mais o código de operação. Todos os operandos correspondem a endereços de
memória; dois são endereços das parcelas, um é o endereço para o armazenamento do
resultado final, e outro é o endereço da próxima instrução. Isto implica em um grande
número de interações com a memória, que não podem ser feitas paralelamente (considerando
a estrutura proposta). Como o tempo de acesso para leitura e escrita de informações para a
memória é grande, se comparado ao tempo empregado para processamento interno à UCP,
este constitui-se em um entrave significativo aos índices de desempenho do computador.
Este entrave é referido como “gargalo de von Neumann”.
Como formas de resolver ou diminuir o problema, pode-se pensar em soluções tais como
diminuir o número de operandos, fazendo com que alguns deles sejam implícitos. Por
exemplo:
• se o resultado de uma operação de soma for armazenado na posição onde inicialmente
está um dos operandos, não é necessário especificar o endereço do resultado
(obviamente neste caso o valor inicial do operando será perdido);
• se o resultado de uma operação de soma for armazenado em uma posição previamente
convencionada, como no endereço seguinte ao de um dos operandos, para citar um
exemplo, ou em uma posição especial de memória destinada só para este fim, não é
necessário especificar o endereço do resultado;
• se o endereço da próxima instrução for previamente convencionado, não há
necessidade de incluí-lo na instrução.
Esta especificação explícita de endereços traz outro inconveniente. No caso do EDVAC, a
memória principal tem 1024 palavras: são necessários 10 bits para endereçá-la. Portanto,
uma instrução aritmética necessitará mais de 40 bits para sua representação (4 x 10 de
endereçamento mais x bits para definição da operação a ser executada) exigindo palavras de
memória grandes ou esquemas especiais de organização de informações.
Estes problemas começaram a ser resolvidos pelo próprio von Neumann na máquina
seguinte, que ficou conhecida pela sigla IAS.
3 . 5 Modelo de von Neumann: o computador IAS
Em 1946, Von Neumann e sua equipe iniciaram o projeto de um novo computador de
programa armazenado: o computador IAS, elaborado no Instituto de Estudos Avançados de
Princeton (Princeton Institute for Advanced Studies). Esta máquina usava como memória
principal um tubo de raios catódicos de acesso randômico, o que permitia o acesso a uma
3-12
palavra inteira em uma única operação. Cada instrução continha somente um endereço de
memória e tinha o seguinte formato:
OP
A
Esta máquina foi largamente divulgada, influenciando sobremaneira o projeto subsequente de
outras máquinas. Os blocos básicos componentes do IAS são:
• uma unidade de processamento central, para execução de operações aritméticas e
lógicas;
• uma unidade de controle de programa, para determinar o sequenciamento das instruções
a serem executadas e gerar os sinais de controle para as outras unidades. Estes sinais
determinam as ações a serem executadas;
• uma unidade de memória principal, com capacidade de 4096 palavras;
• uma unidade de entrada e saída.
As ligações entre estas unidades são mostradas na Figura 3.7.
Unidade Central de Processamento
unidade lógica e aritmética
AC
MQ
circuitos
lógico-aritméticos
equipamento
de
entrada e
saída
DR
instruções
e dados
IBR
PC
memória
principal
IR
AR
circuitos de
controle
: sinais de
:
controle
endereços
Unidade de controle de programa
Figura 3.7 - Estrutura do IAS
Na unidade central de processamento do IAS existe um novo elemento de armazenamento de
dados, que é o acumulador (AC). Este elemento atua como uma memória rápida que guarda
3-13
de forma imediata o resultado das operações realizadas na unidade lógico-aritmética. O
acumulador é empregado intensamente em instruções que realizam estas operações.
Suponha-se a realização de um programa que executa a soma de dois números. Os dois
números a serem somados estão armazenados nas posições 100 e 101 de memória. O
resultado deve ser guardado na posição 102. Na descrição abaixo, a seta (←) indica a
transferência de informação; assim, A ← B significa que A recebe o conteúdo de B
Instrução
AC ← M(100)
AC ← AC + M(101)
M(102) ← AC
Comentários
Transfere conteúdo da memória, end. 100, para acumulador
Soma conteúdo da posição 101 ao conteúdo do acumulador e
coloca o resultado no acumulador
Armazena o conteúdo do acumulador no endereço 102
Figura 3.8 - Exemplo de programa no IAS
Na Figura 3.7 é mostrada a estrutura do computador IAS, cuja arquitetura básica ficou
conhecida como modelo de von Neumann. A terminologia não corresponde exatamente a
utilizada originalmente; os termos estão atualizados para o seu equivalente próximo na
nomenclatura atual.
Organização da memória
A memória do IAS tinha 212 = 4096 palavras, sendo as palavras compostas por 40 bits.
Estes 40 bits, eram a quantidade de informações que podiam ser transferidas, em cada
momento, da UCP para a memória (em um passo). Estas palavras armazenadas na memória
podiam corresponder a instruções ou a dados.
Formato dos dados
Os dados eram números binários representados em ponto fixo e codificados em
complemento de dois. Sendo assim, o bit mais a esquerda do número correspondia ao sinal
do mesmo e as operações de soma e subtração eram ambas executadas por um somador. O
ponto do número estava supostamente entre os bits 0 e 1, permitindo assim a representação
direta apenas de números situados no intervalo entre 0 e 1; os demais números deveriam ser
previamente ajustados antes da realização de cálculos. O formato de um dado é representado
a seguir.
0 1
39
↑
Bit de sinal
Figura 3.9 - Formato dos dados do IAS
Formato das instruções: cada instrução podia ser representada com 20 bits; portanto,
uma palavra de memória podia acomodar 2 instruções. Oito bits, os mais da esquerda ou
“mais significativos” eram usados para o código da operação a ser realizada, e os outros doze
bits eram usados para especificar o endereço de uma posição de memória, conforme
mostrado abaixo.
Instrução posicionada à esquerda
0
8
cód.operação
endereço
Instrução posicionada à direita
19 20
28
cód.operação
Figura 3.10 - Formato das instruções do IAS
3-14
39
endereço
Comparando-se esta instrução com o formato de instrução anteriormente apresentado para o
EDVAC, na qual eram expressos 4 endereços, pode-se observar que ocorreu uma redução
substancial no comprimento da palavra de instrução. As alterações na organização do IAS,
que tornaram possível esta redução são as seguintes:
• há registradores pré-definidos na UCP para armazenarem operandos e resultados,
isto é, os endereços dos registradores da UCP estão implícitos no código de
operação. Assim, as instruções do IAS utilizam estes registradores automaticamente.
• as instruções de um programa estão armazenadas na memória principal de maneira
quase inteiramente seqüencial (excetuando os casos de desvio apenas), considerado o
seguimento que deve ser usado na execução; portanto, o endereço da próxima
instrução é o endereço atual mais 1. Isto elimina a necessidade do campo onde
constava o endereço da próxima instrução. As situações em que devem ocorrer
desvios são resolvidas por instruções especiais.
3 . 5 . 1 Organização da UCP
A UCP do IAS contém alguns registradores para armazenamento temporário de instruções,
endereços de memória e dados. O processamento de dados é realizado pelos circuitos lógicoaritméticos. Os circuitos de controle decodificam instruções, direcionam a informação através
do sistema, e fornecem a temporização dos sinais para todas as ações. Existe um relógio para
a sincronização da operação do sistema. Basicamente, existem as seguintes estruturas, cujas
funções são descritas resumidamente:
• memória principal M: para o armazenamento de programas e dados;
• registrador de dados DR (com 40 bits): recebe dados lidos da posição X da memória
(DR ← M(X)) ou fornece dados que serão gravados na posição X da memória
(M(X) ← DR). Também pode ser usado para armazenar dados temporariamente,
durante a execução de uma instrução;
• registrador de endereços AR (com 12 bits): armazena o endereço que servirá para
apontar posições da memória;
• acumulador AC: armazenamento temporário de operandos;
• registrador multiplicador-quociente MQ: armazenamento temporário de operandos;
• registrador IBR: como no IAS são lidas simultaneamente duas instruções da memória,
a que não é executada imediatamente é armazenada no IBR; a que será executada em
seguida, o código de operação é armazenado no registrador de instruções IR, onde é
decodificado. O campo de endereço desta instrução é transferido para AR;
• contador de programa PC ou registrador de endereço da instrução: armazena o
endereço da próxima instrução a ser executada.
3 . 5 . 2 Conjunto de instruções
As instruções do IAS estão listadas na Tabela 3.3 a seguir. Elas estão divididas em
agrupamentos de acordo com a sua função: instruções de transferência, de desvio
condicional e incondicional, aritméticas e de modificação de endereço.
Para a descrição é usada uma linguagem de transferência a nível de registradores, que
descreve brevemente as instruções e microoperações que ocorrem a nível interno no
computador. As posições de armazenamento são descritas por siglas (como, AR, M), a
transferência de informações é descrita por uma seta, e os elementos de armazenamento
3-15
“matriciais”, como a memória, são especificados por índices entre parênteses. Portanto, na
memória de 4096 x 40, como é o caso do IAS, M(X,0:19) indica os bits de 0 a 19 da palavra
na posição ou endereço X da memória.
Conjunto de instruções do computador IAS
Tipo instrução Notação
Transferência de AC ← MQ
dados
MQ ← M(X)
AC ← M(X)
Descrição
Transfere conteúdo do reg. MQ para o
acumulador AC
Transfere conteúdo da posição X de
memória para MQ
Transfere conteúdo de AC para a posição
de memória X
Transfere M(X) para AC
AC ← – M(X)
Transfere – M(X) para AC
AC ← |M(X)|
Transfere valor absoluto de M(X) para AC
M(X) ← AC
Desvio
incondicional
Desvio
condicional
Aritmética
AC ← – |M(X)|
go to M(X, 0:19)
Transfere – |M(X)| para AC
busque a próxima instrução da metade
esquerda de M(X)
go to M(X, 20:39)
busque a próxima instrução da metade
direita de M(X)
se AC ≥ 0 então desvie se o número em AC não for negativo,
para M(X,0:19)
busque a próxima instrução na metade
esquerda de M(X)
se AC ≥ 0 então desvie se o número em AC não for negativo,
para M(X,20:39)
busque a próxima instrução na metade
direita de M(X)
Some M(X) a AC; resultado em AC
AC ← AC + M(X)
Some |M(X)| a AC; resultado em AC
AC ← AC + |M(X)|
AC ← AC – M(X)
AC ← AC – |M(X)|
Subtraia M(X) de AC; resultado em AC
Subtraia |M(X)| de AC; resultado em AC
Multiplique M(X) por MQ; coloque os bits
mais significativos do resultado em AC e
os menos signif. em MQ
Divida AC por M(X); coloque o quociente
MQ,AC ← AC ÷ M(X)
em MQ e o resto em AC
Multiplique
AC por 2; i.e., desloque em
AC ← AC x 2
um bit à esquerda
Divida AC por 2; i.e., desloque em um bit
AC ← AC ÷ 2
à direita
de M(X,8:19) ← AC(28:39) Substitua campo de endereço à esquerda de
M(X) pelos 12 bits mais à direita de AC
M(X,28:39) ← AC(28:39) Substitua campo de endereço à direita de
M(X) pelos 12 bits mais à direita de AC
AC,MQ ← MQ * M(X)
Modificação
endereço
Tabela 3.3 - Conjunto de instruções do computador IAS
As instruções de transferência possibilitam a transferência entre posições de memória e
registradores da UCP, sem que haja modificação nas informações (exceto nos casos em que
é alterado o sinal). As instruções de desvio fazem com que seja buscado um novo endereço,
para a próxima instrução, na memória (se atendida uma condição, no caso do desvio
condicional). Estas instruções portanto permitem a alteração da seqüência de execução de um
programa.
3-16
As instruções aritméticas fornecem os comandos básicos de processamento de informações
ao computador. As instruções de modificação de endereço permitem o cômputo de endereços
na unidade lógico-aritmética e sua inserção posterior em instruções armazenadas na memória.
Esta propriedade permite que o computador altere suas próprias instruções, o que se constitui
em uma característica importante das máquinas de programa armazenado.
3 . 6 Arquiteturas de 4, 3, 2, 1 e 0 endereços
Enquanto o EDVAC trabalhava basicamente com 4 endereços, o IAS apresentava somente
um endereço. Mesmo assim, ambas arquiteturas possuíam as mesmas capacidades. Para
ilustrar como isto é possível, e também para analisar como a quantidade de endereços de
memória influencia nas instruções e na própria arquitetura, são exemplificadas a seguir
máquinas de 4 endereços (como o EDVAC), de 3 endereços, de 2 endereços, de 1 endereço
(como o IAS) e até as máquinas de zero endereços (por endereço entende-se uma referência à
memória). Ao invés de uma análise detalhada de arquiteturas típicas de cada caso, será
apresentada unicamente a programação de uma equação aritmética:
A = ((B + C)*D + E – F) / (G * H)
As letras A até H denotam posições de memória (endereços), e supõe-se que a arquitetura
analisada possui as quatro operações aritméticas (ADD para soma, SUB para subtração,
MUL para multiplicação e DIV para divisão). O formato exato de cada instrução, assim como
os tamanhos de operandos e instruções são irrelevantes nesta análise.
3 . 6 . 1 Arquitetura de 4 endereços
Em uma arquitetura típica de 4 endereços, as instruções apresentam o formato
OP
E1
E2
E3
E4
onde OP representa a operação a ser realizada, E1 e E2 indicam a localização dos dois
operados fontes desta operação, E3 indica a localização do operando destino (onde o
resultado deve ser armazenado) e E4 indica o endereço onde está localizada a próxima
instrução a ser executada. Note-se que a ordem destes 4 endereços dentro da instrução pode
variar.
Um programa que execute o cálculo da equação acima pode ser visto a seguir. Note-se que
este programa foi otimizado para evitar o uso de outras posições adicionais de memória, e
representa somente uma entre inúmeras implementações possíveis.
Endereço
e1
e2
e3
e4
e5
e6
e7
Instrução
ADD B C A e2
MUL A D A e3
ADD A E A e4
SUB A F A e5
DIV A G A e6
DIV A H A e7
HALT
Comentário
Soma B com C, resultado em A; vai para e2
Multiplica A por D, resultado em A; vai para e3
Soma A com E, resultado em A; vai para e4
Subtrai F de A, resultado em A; vai para e5
Divide A por G, resultado em A; vai para e6
Divide A por H, resultado final em A; vai para e7
Fim do programa
Figura 3.11 - Programa em uma máquina de 4 endereços
Como cada instrução traz implicitamente o endereço da próxima instrução, não existe a
necessidade de instruções explícitas de desvio (como JUMP e BRANCH). Além disto, uma
arquitetura de 4 endereços permite potencialmente a execução de uma operação de
3-17
manipulação de dados e uma operação de desvio do fluxo do programa em uma única
instrução.
Entretanto, a prática demonstrou que normalmente os programas eram escritos
sequencialmente, isto é, uma instrução seguindo a anterior. Com isto modificou-se o
mecanismo de sequenciamento das instruções, o que deu origem às arquiteturas de três
endereços.
3 . 6 . 2 Arquitetura de 3 endereços
Em uma arquitetura típica de 3 endereços, as instruções apresentam o formato
OP
E1
E2
E3
onde OP representa a operação a ser realizada, E1 e E2 indicam a localização dos dois
operados fontes desta operação e E3 indica a localização do operando destino.
Para localizar a próxima instrução a ser executada, criou-se um registrador específico,
denominado de PC (do inglês Program Counter, veja-se seção 3.3.3). Implicitamente, o PC
aponta para o endereço seguinte ao da instrução sendo executada. Assim, o programa fica:
Endereço
e1
e1+1
e1+2
e1+3
e1+4
e1+5
e1+6
Instrução
ADD B C A
MUL A D A
ADD A E A
SUB A F A
DIV A G A
DIV A H A
HALT
Comentário
Soma B com C, resultado em A; incrementa PC
Multiplica A por D, resultado em A; incrementa PC
Soma A com E, resultado em A; incrementa PC
Subtrai F de A, resultado em A; incrementa PC
Divide A por G, resultado em A; incrementa PC
Divide A por H, resultado final em A; incrementa PC
Fim do programa
Figura 3.12 - Programa em uma máquina de 3 endereços
Com a redução de 4 para 3 endereços, existe uma redução do tamanho da instrução e uma
consequente redução do tamanho da memória necessária para armazenar os programas.
Naturalmente, perdeu-se um grau de liberdade: a determinação do endereço da próxima
instrução. Existe agora a necessidade de instruções explícitas de desvio (como JUMP e
BRANCH), e não se pode mais executar simultaneamente uma operação de manipulação de
dados e uma operação de desvio do fluxo do programa em uma única instrução. A economia
de memória, assim como a obrigatoriedade de desenvolvimento de programas sequenciais
(mais fáceis de serem testados, entendidos e corrigidos), entretanto, compensavam este grau
de liberdade perdido.
Instruções de três endereços, entretanto, ainda consomem muita memória. Além disto,
observando-se o programa acima, nota-se que na maioria da vezes um dos operandos fonte e
o operando destino indicam o mesmo endereço (como é o caso do operando A). Com isto
modificou-se a maneira de indicar os operandos, o que deu origem às arquiteturas de dois
endereços.
3 . 6 . 3 Arquitetura de 2 endereços
Em uma arquitetura típica de 2 endereços, as instruções apresentam o formato
OP
E1
E2
onde OP representa a operação a ser realizada, E1 e E2 indicam a localização dos dois
operados fontes desta operação e E1 também indica a localização do operando destino.
Assim, E1 tem dupla função, e não são mais possíveis instruções com três operandos
3-18
distintos. Isto permite uma maior redução nos bits necessários para especificar os endereços
dos operandos, mas introduz uma restrição séria: o resultado da operação será armazenado
no endereço de um dos dois operandos fonte, ou seja, um destes dois operandos será
necessariamente alterado. Esta restrição foi contornada com a criação de uma classe extra de
instruções, as instruções de movimentação de dados, que permitem copiar operandos de uma
posição para outra, conforme pode ser visto no programa a seguir:
Endereço
e1
e1+1
e1+2
e1+3
e1+4
e1+5
e1+6
e1+7
Instrução
MOV A B
ADD A C
MUL A D
ADD A E
SUB A F
DIV A G
DIV A H
HALT
Comentário
Move B para A
Soma A com C, resultado em A
Multiplica A por D, resultado em A
Soma A com E, resultado em A
Subtrai F de A, resultado em A
Divide A por G, resultado em A
Divide A por H, resultado final em A
Fim do programa
Figura 3.13 - Programa em uma máquina de 2 endereços
Comparando-se este programa com o da arquitetura de três endereços, nota-se que a primeira
instrução (ADD B C A) foi substituída por outras duas, uma de movimentação (MOV A B) e
outra de manipulação de dados (ADD A C). O resultado final é o mesmo, mas o programa
possui mais instruções. Entretanto, as instruções são menores, o que em termos líquidos
proporciona uma grande economia de bits.
Com a criação de registradores especiais, pode-se reduzir ainda mais o número de endereços,
criando-se então as arquiteturas de um endereço.
3 . 6 . 4 Arquitetura de um endereço
Em uma arquitetura típica de um endereço, as instruções apresentam o formato
OP
E1
onde OP representa a operação a ser realizada e E1 indica a localização de um operando de
memória (normalmente um dos operandos fontes da operação). O outro operando é
implicitamente assumido como sendo um registrador específico, o acumulador (normalmente
abreviado por AC, veja-se seção 7.2). O Acumulador assume os papéis de um dos
operandos fonte e do operando destino. Em relação às arquiteturas de dois endereços, agora
as instruções de movimentação de dados devem ser subdivididas de acordo com o sentido da
transferência: se da memória para o acumulador (LDA, de LoaD Acumulator), ou se do
acumulador para a memória (STA, de STore Acumulator).O programa exemplo deve ser
conveniente modificado para refletir esta situação (observe-se a instrução extra no fim do
programa):
Endereço
e1
e1+1
e1+2
e1+3
e1+4
e1+5
e1+6
e1+7
e1+8
Instrução
LDA B
ADD C
MUL D
ADD E
SUB F
DIV G
DIV H
STA A
HALT
Comentário
Move B para Acumulador
Soma Acum. com C, resultado no Acumulador
Multiplica Acum. por D, resultado no Acumulador
Soma Acum. com E, resultado no Acumulador
Subtrai F do Acum., resultado no Acumulador
Divide Acum. por G, resultado no Acumulador
Divide Acum. por H, resultado no Acumulador
Armazena Acum. no endereço de A
Fim do programa
Figura 3.14 - Programa em uma máquina de um endereço
3-19
Comparando-se este programa com o da arquitetura de três endereços, nota-se que existem
duas instruções adicionais de transferência de dados, uma no início do programa (LDA B) e
outra no fim (STA A). A grande vantagem deste tipo de arquitetura está na economia dos
acessos à memória: praticamente cada operando foi lido ou escrito uma única vez, o que não
ocorre nas arquiteturas anteriores. Este é justamente o papel dos registradores locais (ou
acumuladores): permitir que resultados intermediários ou dados muito utilizados não
precisem ser lidos ou escritos da memória a cada vez que forem utilizados.
3 . 6 . 5 Arquitetura de zero endereços
Em uma arquitetura típica de zero endereços, as instruções apresentam o formato
OP
ou seja, não existe nenhuma referência explícita a endereços de memória onde estejam
localizados os operandos. Uma possível solução para determinar a posição dos operandos é
colocá-los em uma região específica de memória, com determinado mecanismo de acesso.
Uma estrutura muito utilizada para estes fins é uma pilha: os operandos são sempre retirados
do topo da pilha, e o resultado da operação sempre é colocado no topo da pilha. Para facilitar
a operação desta estrutura de pilha, as equações são escritas utilizando-se notação polonesa
reversa, onde o símbolo da operação é escrito após os dois operandos. Assim, por exemplo,
A+B seria escrito AB+. Com isto, a equação exemplo fica:
HGFEDCB+*+–//
E o programa que a implementa seria:
Endereço
e1
e1+1
e1+2
e1+3
e1+4
e1+5
e1+6
e1+7
e1+8
e1+9
e1+10
e1+11
e1+12
e1+13
e1+14
Instrução
PUSH H
PUSH G
PUSH F
PUSH E
PUSH D
PUSH C
PUSH B
ADD
MUL
ADD
SUB
DIV
DIV
POP A
HALT
Comentário
Coloca H no topo (atual) da pilha
Coloca G no topo da pilha
Coloca F no topo da pilha
Coloca E no topo da pilha
Coloca D no topo da pilha
Coloca C no topo da pilha
Coloca B no topo da pilha
Topo da pilha recebe B+C
(B e C são retirados da pilha)
Topo recebe (B+C)*D
Topo recebe (B+C)*D + E
Topo recebe (B+C)*D + E - F
Topo recebe ((B+C)*D + E - F)/G
Topo recebe ((B+C)*D + E - F)/G*H
Topo da pilha é armazenado em A
Fim do programa
Figura 3.15 - Programa em uma máquina de zero endereços
Note-se que duas instruções (PUSH e POP) na realidade utilizam endereços. Estas são,
entretanto, as duas únicas instruções que necessitam referenciar endereços, e são somente
operações de transferência de dados. Uma arquitetura pura de zero endereços não apresenta
vantagens marcantes sobre arquiteturas de um ou dois endereços, e por causa disto não são
muito difundidas. Os computadores atuais, entretanto, possuem estruturas do tipo pilha para
propósitos específicos. Isto será assunto de outras disciplinas.
3-20
Download