Universidade Federal do Piauí Centro de Tecnologia
Departamento de Engenharia Elétrica
&,5&8,726',*,7$,6,,
Prof. Marcos Zurita
zurita@ufpi.edu.br www.ufpi.br/zurita Teresina - 2011 Macroarquitetura Linguagem de Máquina -2 ì
1. Macroarquitetura
ì2. Emulador do MIC-1
ì
3. O Nível ISA: IJVM
ì 3.1. Pilhas
ì 3.2. Conjunto de Instruções IJVM
3 Circuitos Digitais II – Prof. Marcos Zurita
1. Macroarquitetura
4
Notação das Microinstruções do MIC-1
ì Conforme visto anteriormente, cada microinstrução do
MIC-1 é composta de 36 bits organizados em 6 campos:
ì A descrição de todo o microprograma armazenado na
memória de controle pode ser feita diretamente em binário ou hexadecimal.
ì Entretanto, é conveniente definir uma linguagem
simbólica que permita a abstração de detalhes
desnecessários, mantendo, ao mesmo, a capacidade de controle da máquina ciclo-a-ciclo.
ULA 8 bits C 9 bits Mem 3 bits B 4 bits JAM 3 bits NEXT_ADDRESS 9 bits
5 Circuitos Digitais II – Prof. Marcos Zurita
A Linguagem MAL
ì MAL (Micro Assembly Language) – Linguagem de
montagem de microinstruções;
ì Características:
ì Sintaxe intuitiva;
ì Abstração do endereço da próxima microinstrução;
ì Através de “rótulos” em caso de desvio;
ì Através de inferência automática se não houver desvio.
ì Permite que uma atribuição ou operação incida em mais
de um registrador no mesmo ciclo;
ì Inferência automática do valor dos campos não
explicitados na linha da instrução (valor 0 inferido).
6
ì Cada instrução MAL pode conter os seguintes campos:
ì 1. Rótulo (Label);
ì 2. Atribuição e eventual operação; ì 3. Deslocamento;
ì 4. Operação de acesso à memória; ì 5. Desvio;
ì 6. Comentário.
ì Uma instrução pode não conter nenhum campo. Neste caso
a máquina gastará um ciclo sem fazer nada.
ì Com exceção do Rótulo e do Deslocamento, todos os
demais campos devem ser separados por “;”.
Fuba1: H=MDR >> 1; fetch; goto(MBR) //isto é um comentário
7 Circuitos Digitais II – Prof. Marcos Zurita
Comentários
ì Podem ser inseridos através de “//”, colocando como
comentário tudo que estiver à sua direita na linha.
Rótulos (Labels)
ì Quando utilizado, deve ser o primeiro campo a ser
escrito e deve ser separado dos demais campos por “:”.
ì Um Rótulo pode conter qualquer caractere alfanumérico,
exceto espaços em branco.
MAR = 0; // isto aqui é um comentário
Inicio: OPC = PC-1; // esta linha tem como rótulo “Inicio”
H = MDR; // esta linha não possui nenhum rótulo
Eita 1: H = TOS; // este rótulo é inválido pois possui // um espaço em branco
8
Atribuição e Eventual Operação
ì Pode envolver qualquer registrador como operando ou
destino, observando-se as características do MIC-1: ì MBR não pode ser destino de operação ou atribuição; ì MAR não pode ser operando, apenas destino.
REGISTRADOR DESTINO FONTE OU OPERANDO CPP X X H X X LV X X MAR X MBR X MBRU X MDR X X OPC X X PC X X SP X X TOS X X
9 Circuitos Digitais II – Prof. Marcos Zurita
ì A tabela abaixo lista todas as operações e atribuições
possíveis pela MAL do MIC-1:
N° OPERAÇÃO EXEMPLO
1 DEST = H TOS = H;
2 DEST = FONTE OPC = PC;
3 DEST = H LV = not(H);
4 DEST = FONTE SP = not(MDR);
5 DEST = H + FONTE CPP = H + TOS;
6 DEST = H + FONTE +1 CPP = H + TOS + 1;
7 DEST = H + 1 LV = H + 1;
8 DEST = FONTE + 1 PC = PC + 1;
9 DEST = FONTE - H MDR = TOS - H;
10 DEST = FONTE - 1 PC = OPC - 1;
11 DEST = -H H = -H;
12 DEST = H AND FONTE OPC = H AND MBRU;
13 DEST = H OR FONTE SP = H OR TOS;
14 DEST = 0 PC = 0;
15 DEST = 1 H = 1;
16 DEST = -1 MDR = -1;
10
H=OPC=TOS=CPP=LV=SP=PC = MDR + H + 1;
ì Deve-se notar também que o “Destino” especificado na
tabela anterior pode conter mais de um registrador. Ex.:
ì A linguagem adotada suporta ainda a comutatividade de
operandos nas operações de soma e lógica binária. Ex.:
ì Em todos os exemplos acima, a microinstrução gerada
será a mesma do código equivalente, pois no MIC-1 o registrador H é sempre o operador esquerdo da ULA.
MDR = SP + H; // equivale a “MDR = H + SP”
CPP = TOS + H + 1; // equivale a “CPP = H + TOS + 1” LV = 1 + H; // equivale a “LV = H + 1”
H = MBR OR H; // equivale a “H = H OR MBR” TOS = MDR AND H; // equivale a “TOS = H AND MDR”
11 Circuitos Digitais II – Prof. Marcos Zurita
ì Por outro lado, algumas operações simples são ilegais
nesta linguagem, devido à limitações impostas pela microarquitetura do MIC-1. Ex.:
Solução aos exemplos:
H = H – MDR; // operação ilegal, pois a única fonte // possível para o subtraendo (valor a ser // subtraído) deve estar no registrador H MDR = SP + MDR; // operação ilegal, pois exige a leitura // dos registradores SP e MDR via
// barramento B no mesmo ciclo
H = SP; // copia o valor de SP para MDR
MDR = H + MDR; // efetua a soma de MDR com a cópia de SP H = MDR - H; // efetua a subtração inversa
H = -H; // desinverte o sinal gerando “H = H - MDR”
12
Deslocamento
ì Quando empregados, devem vir após uma atribuição ou
operação, sem o separador “;”.
ì Dois tipos de deslocamento são possíveis:
ì Deslocamento de 8 bits à esquerda (<< 8); ì Deslocamento de 1 bit à direita (>> 1).
ì Os deslocamentos possíveis estão listados na tabela
abaixo.
ì Deve-se salientar que por “Operação” entende-se
qualquer uma das listadas na tabela do slide 9.
N° DESLOCAMENTO EXEMPLO
1 DEST = OPERAÇÃO << 8; H = 1 << 8;
13 Circuitos Digitais II – Prof. Marcos Zurita
Desvio
ì Três operações de desvio são possíveis:
ì Desvio incondicional; ì Desvio condicional; ì Desvio multidirecional.
ì Desvio Incondicional – pode ser feito através da
notação goto Rótulo. Por exemplo:
Main1: PC = PC+1; // linha de rótulo “Main1” H = MBR; // linha sem rótulo
TOS = 0; goto Main1 // zera TOS e vai para “Main1”
14 ì Desvio Condicional - pode ser feito através da notação:
if(X) goto L1; else goto L2
ì Onde X pode ser o registrador Z ou N, L1 e L2 dois
labels pertencentes as 256 primeiras linhas de instrução. Por exemplo:
ì Como um desvio condicional baseia-se no valor de N
ou Z, a linguagem exige que ela seja utilizada junta-mente com uma atribuição ou operação.
H = 1 << 8; // faz H = 256
Denovo: H = H-1; if(Z) goto Zerou; else goto Denovo Zerou: MDR = MDR+1;
R1: if(N) goto R1; else goto R2 // este desvio é ilegal // pois não está associado a uma operação
15 Circuitos Digitais II – Prof. Marcos Zurita
ì Eventualmente, pode-se desejar testar um determinado
registrador, sem se alterar seu conteúdo.
ì Uma alternativa para isto seria fazê-lo passar pela ULA e
armazena-lo de volta (auto-atribuição). Ex.:
ì Entretanto, para tornar isto mais visível, a MAL é capaz
de aceitar atribuições diretas a N ou Z, gerando implici-tamente uma auto-atribuição do registrador.
ì A microinstrução gerada neste caso é exatamente igual
a do exemplo anterior.
R1: MDR = MDR; if(Z) goto R2; else goto R1 // testa MDR
R2: TOS = TOS-1;
R1: Z = MDR; if(Z) goto R2; else goto R1 // testa MDR
R2: TOS = TOS-1;
16 ì Desvio Multidirecional - é desvio cujo destino depende
do conteúdo do registrador MBR.
ì Pode ser feito através da notação:
goto (MBR or valor_de_9_bits)
ì Se o valor_de_9_bits for nulo, basta escrever:
goto (MBR)
ì Este é o tipo de desvio utilizado para se executar
instruções cujo opcode foi buscado na memória.
bola7: PC = PC+1; // linha de rótulo “bola7” H = MBR; // copia o opcode para H
17 Circuitos Digitais II – Prof. Marcos Zurita
Operação de Acesso à Memória
ì Três operações de acesso à memória são possíveis:
ì Leitura de um dado de 32 bits via MAR/MDR (rd);
ì Escrita de um dado de 32 bits via MAR/MDR (wr);
ì Busca de um opcode de 8 bits via PC/MBR (fetch).
ì A busca de um opcode pode ocorrer simultaneamente
(mesmo ciclo) que uma leitura ou escrita na memória.
MAR = SP-1; rd // ajusta MAR e ordena leitura
PC = PC+1; fetch; wr // ajusta PC e ordena busca/escrita TOS = TOS+1; wr // ajusta TOS e ordena escrita
PC = PC+1; fetch // ajusta PC e ordena busca
18
ì Ao fazer uso de operações de acesso à memória,
deve-se ter em mente a latência imposta por ela, isto é:
ì 1. Operações de leitura e busca (rd/fetch) só atualizam
seus respectivos registradores (MDR/MBR) no final do ciclo seguinte, ou seja:
ì ÖÖÖÖ O resultado de uma leitura ou busca em memória só
pode ser utilizado em atribuições ou operações 2 ciclos após ordenada a leitura ou busca.
MAR = SP = SP-1; rd // ajusta MAR e SP e ordena leitura // aguarda a leitura do valor em MDR TOS = MDR; // copia o valor lido para TOS
PC = PC+1; fetch; // ajusta PC e ordena busca/escrita LV = LV+1; // incrementa LV e aguarda a busca MDR = MBR; // copia o opcode lido para MDR
19 Circuitos Digitais II – Prof. Marcos Zurita
ì 2. Outra consequência da observação feita em “1” é: ì ÖÖÖÖ MDR não pode ser modificado no ciclo seguinte a
uma ordem de leitura pois a memória também irá escrever nele, gerando um conflito.
ì 3. Apesar da escrita do opcode buscado na memória só
ocorrer no final do ciclo seguinte ao da ordem, o cálculo do novo MPC só será feito após essa escrita, ou seja:
ì ÖÖÖÖ MBR pode ser utilizado em instruções de desvio no
ciclo imediatamente seguinte ao da ordem de busca.
MAR = SP; rd // ajusta MAR e ordena leitura
MDR = H; // a memória também irá escrever em MDR neste // mesmo ciclo! O valor em MDR é indefinido.
PC = PC+1; fetch // ajusta PC e ordena busca
goto(MBR) // o novo MBR já pode ser usado para desvio
20
ì 4. Operações de escrita (wr) só utilizam os registradores
MAR e MDR no ciclo corrente, isto é:
ì ÖÖÖÖ MAR e MDR podem ser modificados no ciclo
seguinte a uma ordem de escrita sem penalidade na gravação do valor antigo na memória.
MDR = H << 8; // ajusta MDR
MAR = MBRU+H; wr // ajusta MAR e ordena escrita
21 Circuitos Digitais II – Prof. Marcos Zurita
2. Emulador do MIC-1
22
Emulador do MIC-1
ì “emuMIC” - desenvolvido por estudantes da UNICT
(Università degli Studi di Catania), sob orientação do Prof. Franco Barbanera, na Itália.
ì Características:
ì Licença GPL;
ì Feito em Java (roda na maior parte dos computadores); ì Emula completamente a microarquitetura do MIC-1;
ì Capaz de executar as microinstruções subciclo-a-subciclo; ì Possui um micromontador MAL integrado, permitindo a
escrita das microinstruções na linguagem MAL;
ì Disponível em: www.dmi.unict.it/~barba/Architetture.html
23 Circuitos Digitais II – Prof. Marcos Zurita
24
3. O Nível ISA: IJVM
25 Circuitos Digitais II – Prof. Marcos Zurita
ì
Pilhas
ì
O Modelo de Memória do IJVM
ì
Conjunto de Instruções IJVM
ì
Compilação JAVA
26
3.1. Pilhas
27 Circuitos Digitais II – Prof. Marcos Zurita
Pilhas
ì Quase todas as linguagens de programação suportam o
conceito de sub-rotinas, que por sua vez possuem suas próprias variáveis, as chamadas variáveis locais.
ì Variáveis locais
ì Variáveis “visíveis” apenas pela sub-rotina que as criou. ì São “criadas” no momento que sub-rotina é chamada e
“destruídas” ao seu término, liberando a memória por elas ocupada.
ì Variáveis globais
ì São variáveis “visíveis” em todo o programa.
ì Criadas na execução do programa e destruídas no seu
encerramento.
28
ì
Ex.: Variáveis globais e locais em C
#include <stdio.h>
#include "interface.h" // biblioteca externa
int t_ref = 273; // variável global
void print_temp() // sub-rotina
{
int t_kelvin; // variável local
t_kelvin = lePorta1() + t_ref; // t_ref é visível aqui
printf("Temperatura = %i Kelvin", t_kelvin); }
void main() // rotina principal
{
int j=0; // variável local
while (1) { // laço infinito
if (j==100) { print_temp(); j=0; }
else { j++ } }
29 Circuitos Digitais II – Prof. Marcos Zurita
ì Reservar um espaço na memória para variáveis globais
não constitui, a princípio, um problema:
ì Pode-se fazê-lo simplesmente fixando um endereço na
memória para cada variável e referenciando-se tais ende- reços de qualquer ponto do programa para acessá-las
ì Por outro lado, como proceder com as variáveis locais?
ì A solução sugerida para variáveis globais não funciona
pois uma sub-rotina pode chamar a si mesma
(recursividade), o que sobrescreveria as varáveis da primeira execução. Ex.:
void procura_obst(int v) { // sub-rotina
int k; // variável local
k = lePorta2() + v;
if (k > 127) { printf("obstáculo encontrado!"); }
else { procura_obst(k); } // Recursão: a sub-rotina
} // chama a si mesma
30 ì A solução para a alocação de variáveis locais na
memória é a adoção do conceito de pilha (stack).
ì Pilha
ì É uma área da memória reservada para o
armazenamento de variáveis locais;
ì Nela, variáveis são “empilhadas”, umas
sobre as outras, de modo que o topo da pilha contém sempre as variáveis mais recentemente criadas;
ì Sua implementação requer dois
apontadores:
ì 1°: Apontador para a base da pilha ( LV) ì 2°: Apontador para o topo da pilha ( SP)
var_5 var_4 var_3 var_2 var_1 P I L H A SP ĺ LV ĺ
31 Circuitos Digitais II – Prof. Marcos Zurita
ì Neste conceito as variáveis locais não referenciadas por seu endereço absoluto na memória e sim por sua
posição relativa à base da pilha (LV).
ì Sempre que uma sub-rotina é chamada, o apontador da
base da pilha (LV) é ajustado para apontar o endereço base das variáveis locais da sub-rotina corrente.
ì Da mesma forma, o apontador de topo da pilha (SP)
também deve ser ajustado para indicar o endereço absoluto da última variável local da sub-rotina corrente.
ì No MIC-1, a quantidade de memória consumida pelas
varáveis locais de uma sub-rotina pode ser calculada (após sua alocação) através da fórmula:
(Eq. 3.1)
Mem
SUB4SPLV 1
32
ì
Ex.: Alocação de variáveis locais em C
ì 1. main1() é executada;
ì 2. main1() chama a
sub-rotina subA(); void subD() { long d[5]; } void subC() { long c1, c2; // instruções... } void subB() { long b1, b2, b3, b4; subC(); // instruções... } void subA() {
long a1, a2, a3; subB(); subD(); }
void main() { subA(); }
33 Circuitos Digitais II – Prof. Marcos Zurita
ì
Ex.: Alocação de variáveis locais em C
ì 3. subA() cria as variáveis
locais a1, a2 e a3;
ì Admitindo que a pilha comece
no endereço 100, e que cada variável ocupe 4 bytes, temos:
ì LV = 100 (endereço absoluto); ì SP = 108 (endereço absoluto); ì a1 ĺ endereço relativo = 0; ì a2 ĺ endereço relativo = 4; ì a3 ĺ endereço relativo = 8. void subD() { long d[5]; } void subC() { long c1, c2; // instruções... } void subB() { long b1, b2, b3, b4; subC(); // instruções... } void subA() {
long a1, a2, a3; subB(); subD(); } void main() { subA(); } SP ĺ a3 108 a2 104 LV ĺ a1 100 Quadro de variáveis locais de subA() 34
ì
Ex.: Alocação de variáveis locais em C
ì 4. subA() chama subB();
ì 5. subB() cria as variáveis
locais b1, b2, b3 e b4: ì LV = 112 (endereço absoluto); ì SP = 124 (endereço absoluto); ì b1 ĺ endereço relativo = 0; ì b4 ĺ endereço relativo = 12; void subD() { long d[5]; } void subC() { long c1, c2; // instruções... } void subB() { long b1, b2, b3, b4; subC(); // instruções... } void subA() {
long a1, a2, a3; subB(); subD(); } void main() { subA(); } SP ĺ a3 108 a2 104 LV ĺ a1 100 SP ĺ b4 124 b3 120 b2 116 LV ĺ b1 112 a3 108 a2 104 a1 100 Quadro de variáveis locais de subB()
35 Circuitos Digitais II – Prof. Marcos Zurita
ì
Ex.: Alocação de variáveis locais em C
ì 6. subB() chama subC();
ì 7. subC() cria as variáveis
locais c1 e c2: ì LV = 128; ì SP = 132. void subD() { long d[5]; } void subC() { long c1, c2; // instruções... } void subB() { long b1, b2, b3, b4; subC(); // instruções... } void subA() {
long a1, a2, a3; subB(); subD(); } void main() { subA(); } SP ĺ b4 124 b3 120 b2 116 LV ĺ b1 112 a3 108 a2 104 a1 100 SP ĺ c2 132 LV ĺ c1 128 b4 124 b3 120 b2 116 b1 112 a3 108 a2 104 a1 100 36
ì
Ex.: Alocação de variáveis locais em C
ì 8. subC() termina,
restauran-do os valores anteriores de SP e LV, liberando a memória ocupada por c1 e c2: ì LV = 112; ì SP = 124. void subD() { long d[5]; } void subC() { long c1, c2; // instruções... } void subB() { long b1, b2, b3, b4; subC(); // instruções... } void subA() {
long a1, a2, a3; subB(); subD(); } void main() { subA(); } SP ĺ c2 132 LV ĺ c1 128 b4 124 b3 120 b2 116 b1 112 a3 108 a2 104 a1 100 c2 c1 SP ĺ b4 124 b3 120 b2 116 LV ĺ b1 112 a3 108 a2 104 a1 100
37 Circuitos Digitais II – Prof. Marcos Zurita
ì
Ex.: Alocação de variáveis locais em C
ì 9. subC() devolve a
execução para subB();
ì 10. subB() termina,
restau-rando SP e LV, liberestau-rando a memória de b1, b2, b3 e b4: ì LV = 100; ì SP = 108. void subD() { long d[5]; } void subC() { long c1, c2; // instruções... } void subB() { long b1, b2, b3, b4; subC(); // instruções... } void subA() {
long a1, a2, a3; subB(); subD(); } void main() { subA(); } SP ĺ b4 124 b3 120 b2 116 LV ĺ b1 112 a3 108 a2 104 a1 100 b4 124 b3 120 b2 116 b1 112 SP ĺ a3 108 a2 104 LV ĺ a1 100 38
ì
Ex.: Alocação de variáveis locais em C
ì 11. subB() devolve a
execução para subA();
ì 12. subA() chama subD();
void subD() { long d[5]; } void subC() { long c1, c2; // instruções... } void subB() { long b1, b2, b3, b4; subC(); // instruções... } void subA() {
long a1, a2, a3; subB(); subD(); } void main() { subA(); } SP ĺ a3 108 a2 104 LV ĺ a1 100
39 Circuitos Digitais II – Prof. Marcos Zurita
ì
Ex.: Alocação de variáveis locais em C
ì 13. subD() cria as variáveis
locais d[0] à d[4]:
ì LV = 112; SP = 128.
ì As variáveis de subD() ocupam o
mesmo espaço anteriormente
ocupado pelas variáveis de subB()
e parte das de subC().
void subD() { long d[5]; } void subC() { long c1, c2; // instruções... } void subB() { long b1, b2, b3, b4; subC(); // instruções... } void subA() {
long a1, a2, a3; subB(); subD(); } void main() { subA(); } SP ĺ d[4] 128 d[3] 124 d[2] 120 d[1] 116 LV ĺ d[0] 112 a3 108 a2 104 a1 100 40
Pilha de Operandos
ì São regiões da pilha (ou mesmo pilhas dedicadas)
voltadas ao armazenamento de operandos durante o cálculo de uma expressão aritmética
ì Seu tamanho pode variar durante a operação.
ì Ex.: Suponha que a sub-rotina subA(), antes de
chamar subB(), precise calcular
a1 = a2 + a3;
ì Suponha que esta soma seja feita por uma instrução no
nível ISA, chamada IADD que retira os dois últimos
registros da pilha, soma-os e devolve o resultado para o topo da pilha.
41 Circuitos Digitais II – Prof. Marcos Zurita
ì A execução dessa linha de código (a1=a2+a3) pode ser
resumida pelos seguintes passos:
ì 1. O operando a2 é copiado para o topo da pilha; ì 2. O operando a3 é copiado para o topo da pilha; ì 3. A instrução IADD é chamada;
ì 4. IADD retira os operandos da pilha e soma-os;
ì 5. IADD coloca o resultado da soma no topo da pilha; ì 6. O resultado é movido para a1 e SP ajustado.
SP ĺ a3 116 a2 112 a3 108 a2 104 LV ĺ a1 100 SP ĺ a2 112 a3 108 a2 104 LV ĺ a1 100 SP ĺ a2+a3 112 a3 108 a2 104 LV ĺ a1 100 SP ĺ a3 108 a2 104 LV ĺ a2+a3 100 IADD 42
3.2. O Modelo de Memória do IJVM
43 Circuitos Digitais II – Prof. Marcos Zurita
Partes da Memória IJVM
ì A Memória do IJVM é dividida em 4 partes:
ì Área do Procedimento
ì Quadro de Variáveis Locais ì Pilha de Operandos ì Pool de Constantes Pool de Constantes ĸCPP Área do Procedimento (Método) ĸ PC Pilha 3 – Operandos Correntes ĸ SP Quadro 3 – Variáveis Locais Correntes ĸ LV Quadro 2 – Variáveis Locais Quadro 1 – Variáveis Locais 44
O Pool de Constantes
ì Não pode ser escrita pelos programas IJVM;
ì Contém constantes, strings e ponteiros para endereços
de memória;
ì O registrador CPP (Constant Pool Pointer) aponta para a
primeira palavra do pool de constantes.
O Quadro de Variáveis Locais
ì No início guarda valores dos parâmetros (argumentos)
do procedimento (método) chamado;
ì O registrador LV (Local Vars) contém o endereço da
45 Circuitos Digitais II – Prof. Marcos Zurita
A Pilha de Operandos
ì Fica imediatamente acima do quadro de variáveis locais;
ì Seu tamanho não pode ultrapassar um determinado
limite pré-determinado pelo compilador JAVA;
ì Registrador SP (Stack Pointer):
ì Armazena o endereço do topo da pilha;
ì Muda de valor durante a execução do procedimento.
A Área do Procedimento
ì Região de memória que armazena o programa;
ì O registrador PC (Program Counter) aponta para o
endereço da próxima instrução a ser buscada.
46
3.3. Conjunto de Instruções IJVM
47 Circuitos Digitais II – Prof. Marcos Zurita
O Conjunto de Instruções da IJVM
Hexa Mnemônico Significado
0x10 BIPUSH byte Carregue um byte na pilha
0x59 DUP Copia a palavra do topo da pilha e passe-a para a pilha 0xA7 GOTO offset Desvio incondicional
0x60 IADD Retire duas palavras da pilha; carregue sua soma 0x7E IAND Retire duas palavras da pilha; carregue AND booleano 0x99 IFEQ offset Retire uma palavra da pilha e desvie se for zero
0x9B IFLT offset Retire uma palavra da pilha e desvie se for menor que zero 0x9F IF _ICMPEO offset Retire duas palavras da pilha e desvie se elas forem iguais 0x84 IINC varnum const Some uma constante a uma variável local
0x15 ILOAD varnum Coloque uma variável local no topo da pilha 0xB6 INVOKEVIRTUAL disp Chame uma sub-rotina (método)
0x80 IOR Retire duas palavras da pilha; carregue OR booleano 0xAC IRETURN Retorne da sub-rotina (método) com um valor inteiro
0x36 ISTORE varnum Retira a palavra da pilha e armazene-a numa variável local 0x64 ISUB Retire duas palavras da pilha; carregue sua diferença 0x13 LDC_W index Carregue constante do conjunto de constantes para a pilha 0x00 NOP Não faz nada
0x57 POP Retire a palavra do topo da pilha
0x5F SWAP Troca as duas palavras do topo da pilha uma pela outra 0xC4 WIDE Prefixo de instrução; a próxima instrução tem índice de 16 bits
48
Código de Máquina das Instruções IJVM
ì As instruções IJVM implementadas no MIC-1 podem
ocupar 8, 16, 24 ou 32 bits de espaço na memória.
OPCODE 8 bits
OPCODE ARG_1 8 bits 8 bits
OPCODE ARG_1 ARG_2
8 bits 8 bits 8 bits
WIDE OPCODE ARGUMENTO
49 Circuitos Digitais II – Prof. Marcos Zurita
Instruções de 8 bits
ì São instruções que não requerem argumentos ou que
não possuem argumentos explícitos:
ì DUP ì IADD ì ISUB ì IAND ì IOR ì IRETURN ì NOP ì POP ì SWAP ì WIDE*
* Trata-se, na verdade, de um prefixo de instrução.
50
Instruções de 16 bits
ì São instruções recebem um argumento explícito de 8
bits como parâmetro:
ì BIPUSH ì IINC* ì ILOAD* ì ISTORE
* Podem receber também argumentos de 16 bits, neste caso passam a ser instruções de 32 bits.
51 Circuitos Digitais II – Prof. Marcos Zurita
Instruções de 24 bits
ì São instruções recebem um argumento explícito de 16
bits como parâmetro ou dois argumentos de 8 bits:
ì GOTO ì IFEQ ì IFLT ì IF_ICMPEQ ì INVOKEVIRTUAL ì LDC_W 52 Instruções de 32 bits
ì As instruções ILOAD e ISTORE, em suas versões de 16
bits, recebem como parâmetro variáveis locais cujo endereço relativo não ultrapassa 255, utilizando com isso apenas argumentos de 8 bits.
ì Caso o endereço relativo da variável local seja superior
a 255, é necessário um argumento de 16 bits como parâmetro.
ì Naturalmente, a implementação das versões estendidas
dessas instruções (com parâmetros de 16 bits) difere da implementação com parâmetros de 8 bits.
ì Consequentemente, um novo microcódigo deverá ser
criado para implementar as versões estendidas de ILOAD e ISTORE.
53 Circuitos Digitais II – Prof. Marcos Zurita
ì Isto pode ser obtido basicamente de 2 formas:
ì 1. criando um novo opcode para cada versão estendida:
limita o novo opcode a ocupar um dos espaços vazios entre as instruções nos primeiros 256 endereços da memória de controle;
ì 2. criando uma instrução especial capaz de redirecionar o opcode seguinte para um endereço na parte alta da
memória de controle, onde se encontra a implementação da versão estendida da instrução em questão.
ì O mecanismo adotado pelo IJVM é a segunda solução.
ì A instrução especial criada para esta finalidade é o
prefixo “WIDE”, consumindo 8 bits.
ì Os demais 24 bits ficam no opcode da instrução que se
segue (8 bits) e no seu argumento (16 bits).
54
Implementação das Instruções IJVM em MAL
ì Todas as instruções IJVM devem garantir em sua
imple-mentação a execução da instrução seguinte.
ì Por essa razão, a instrução interna “Main1” é chamada
ao final da implementação de cada instrução IJVM:
ì Main1 é responsável por 3 operações:
ì 1. Incremento do PC, fazendo com que ele aponte para o
primeiro byte após o opcode que será executado;
ì 2. Início da busca do próximo byte e armazenamento dele no
MBR (que ocorrerá no final do ciclo seguinte);
ì 3. Desvio para o endereço apontado pelo valor corrente de
MBR, isto é, execução da instrução cujo opcode foi armaze-nado no MBR pela instrução chamadora de Main1.
55 Circuitos Digitais II – Prof. Marcos Zurita
A Instrução NOP
ì Código IJVM:
ì Não faz nada durante um ciclo.
ì Esta instrução é propositalmente localizada no endereço
0x00, sendo portanto a primeira instrução a ser executa-da quando a máquina MIC-1 é inicializaexecuta-da (MPC=0x000 no reset).
Implementação em Microcódigo MAL
0x00 nop1: goto Main1
NOP 0x00
56
IADD
ì Código IJVM:
ì Retira duas palavras do topo da pilha de operandos,
soma as duas e coloca o resultado no topo.
Implementação em Microcódigo MAL
0x60 iadd1: MAR=SP=SP-1; rd
iadd2: H=TOS
iadd3: MDR=TOS=MDR+H; wr; goto Main1
IADD 0x60
57 Circuitos Digitais II – Prof. Marcos Zurita
ISUB
ì Código IJVM:
ì Retira duas palavras do topo da pilha de operandos,
subtrai as duas e coloca o resultado no topo.
Implementação em Microcódigo MAL
ISUB 0x64
0x64 isub1: MAR=SP=SP-1; rd
isub2: H=TOS
isub3: MDR=TOS=MDR-H; wr; goto Main1
58
BIPUSH
ì Código IJVM:
ì Coloca o BYTE especificado como parâmetro no topo da
pilha de operandos.
Implementação em Microcódigo MAL
0x10 bipush1: SP=MAR=SP+1
bipush2: PC=PC+1; fetch
bipush3: MDR=TOS=MBR; wr; goto Main1
BIPUSH byte
59 Circuitos Digitais II – Prof. Marcos Zurita
ILOAD
ì Código IJVM:
ì Copia o conteúdo da variável local especificada como
parâmetro no topo da pilha de operandos.
Implementação em Microcódigo MAL
0x15 iload1: H=LV;
iload2: MAR=MBRU+H; rd iload3: MAR=SP=SP+1
iload4: PC=PC+1; fetch; wr iload5: TOS=MDR; goto Main1
ILOAD varnum 0x15 variável
60
ISTORE
ì Código IJVM:
ì Retira a palavra que está no topo da pilha de operandos
e a armazena na variável local especificada.
Implementação em Microcódigo MAL
0x36 istore1: H=LV;
istore2: MAR=MBRU+H
istore3: MDR=TOS; wr istore4: SP=MAR=PC-1; rd istore5: PC=PC+1; fetch
istore6: TOS=MDR; goto Main1
ISTORE varnum 0x36 variável
61 Circuitos Digitais II – Prof. Marcos Zurita
IINC
ì Código IJVM:
ì Soma um valor constante a uma variável local passada
como parâmetro.
Implementação em Microcódigo MAL
IINC varnum const 0x84 variável constante 0x84 iinc1: H=LV; iinc2: MAR=MBRU+H; rd iinc3: PC=PC+1; fetch iinc4: H=MDR iinc5: PC=PC+1; fetch
iinc6: MDR=MBR+H; wr; goto Main1
62
GOTO
ì Código IJVM:
ì Desvia incondicionalmente a execução do programa
para o endereço relativo especificado.
Implementação em Microcódigo MAL
0xA7 goto1: OPC=PC-1
goto2: PC=PC+1; fetch goto3: H=MBR << 8
goto4: H=MBRU OR H
goto5: PC=OPC+H; fetch goto6: goto Main1
GOTO offset
63 Circuitos Digitais II – Prof. Marcos Zurita
IF_ICMPEQ
ì Código IJVM:
ì Retira 2 palavras do topo da pilha, se elas forem iguais,
desvia a execução para o endereço relativo especificado.
Implementação em Microcódigo MAL
0x9F if_icmpeq1: MAR=SP=SP-1; rd
if_icmpeq2: MAR=SP=SP-1
if_icmpeq3: H=MDR; rd if_icmpeq4: OPC=TOS
if_icmpeq5: TOS=MDR
if_icmpeq6: Z=OPC-H; if(Z) goto T; else goto F T: OPC=OPC-1; fetch; goto goto2
F: PC=PC+1 F2: PC=PC+1; fetch F3: goto Main1 IF_ICMPEQ offset 0x9F offset[15..8] offset[7..0] 64
WIDE
ì Código IJVM:ì Não é propriamente uma instrução e sim um prefixo de
instrução, indicando que a próxima instrução tem um parâmetro de 16 bits.
ì O byte que se segue ao prefixo deve conter o opcode da
instrução a ser executada na parte alta da memória de controle (parte cujo endereço é superior a 0x100), para isso o opcode será somado a 0x100 e executado.
Implementação em Microcódigo MAL
0xC4 wide1: PC=PC+1; fetch; goto (MBR or 0x100)
WIDE 0xC4
65 Circuitos Digitais II – Prof. Marcos Zurita
WIDE_ILOAD
ì Código IJVM:
ì Versão estendida da instrução ILOAD, capaz de operar
com variáveis cujo endereço relativo é superior a 255;
ì Seu microcódigo encontra-se na parte alta da memória
de controle (ADDR 0x100), sendo executado através do prefixo WIDE.
Implementação em Microcódigo MAL
ILOAD varnum
0xC4 0x15 variável[15..8] variável[7..0]
0x115 wide_iload1: PC=PC+1; fetch
wide_iload2: H=MBRU << 8
wide_iload3: H=MBRU OR H
wide_iload4: MAR=LV+H; rd; goto iload3
66
WIDE_ISTORE
ì Código IJVM:
ì Versão estendida da instrução ISTORE, capaz de operar
com variáveis cujo endereço relativo é superior a 255;
ì Seu microcódigo encontra-se na parte alta da memória
de controle (ADDR 0x100), sendo executado através do prefixo WIDE.
Implementação em Microcódigo MAL
ISTORE varnum
0xC4 0x36 variável[15..8] variável[7..0]
0x136 wide_istore1: PC=PC+1; fetch
wide_istore2: H=MBRU << 8
wide_istore3: H=MBRU OR H
67 Circuitos Digitais II – Prof. Marcos Zurita
3.4. Inicialização do MIC-1
68
Processo de Inicialização do MIC-1
ì Ciclo 0: A máquina é inicializada. Todos os
registradores são zerados, inclusive o apontador de microprograma (MPC=0x000).
ì 1° ciclo : Como a instrução NOP está estrategicamente
localizada no endereço 0x000 da memória de controle, será ela a primeira instrução a ser executada, desviando a execução para Main1.
ì 2° ciclo : Main1 incrementa PC e inicia a busca da
instrução no endereço apontado por ele (PC=1). Como MBR ainda é igual a zero, a execução é desviada
69 Circuitos Digitais II – Prof. Marcos Zurita
ì 3° ciclo : NOP consome um ciclo sem fazer nada
enquanto a primeira instrução cuja busca iniciou no ciclo anterior é transferida da memória para MBR.
ì A execução é novamente desviada para Main1.
ì 4° ciclo: Main1 é executada novamente, incrementando
PC para 2 e iniciando a busca do próximo byte (que poderá ser o opcode da próxima instrução ou um argumento da instrução corrente).
ì MBR contém agora o opcode da primeira instrução IJVM
da memória (armazenada no endereço 0x01).
ì Com isso, goto (MBR) agora desviará a execução para o
endereço da memória de controle correspondente à instrução IJVM apontada por MBR.
70
ì 5° ciclo em diante: A execução continuará por um ou mais
ciclos, conforme a duração da instrução IJVM chamada.
ì Ao final do microprograma, a execução será desviada
novamente para Main1.
ì Neste ponto, o próximo opcode já deverá ter sido
carregado em MBR, fazendo com que Main1 inicie a busca seguinte e execute a próxima instrução IJVM.
ì O processo se repete dando prosseguimento a execução
do programa armazenado na memória até que alguém desligue a máquina.
71 Circuitos Digitais II – Prof. Marcos Zurita
3.5. Compilação JAVA
72
Compilação JAVA para IJVM
ì Considere o fragmento de código JAVA abaixo: ì O equivalente IJVM obtido por compilação seria:
1 i = j + k; 2 if (i == 3) 3 k = 0; 4 else 5 j = j - 1; JAVA 1 ILOAD j 2 ILOAD k 3 IADD 4 ISTORE i 5 ILOAD i 6 BIPUSH 3 7 IF_ICMPEQ L1 8 ILOAD j 9 BIPUSH 1 10 ISUB 11 ISTORE j 12 GOTO L2 13 L1: BIPUSH 0 14 ISTORE k 15 L2: IJVM
73 Circuitos Digitais II – Prof. Marcos Zurita
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha 2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k” 4 ISTORE i // retira resultado do topo e coloca em i 5 ILOAD i // copia a variável i para o topo da pilha 6 BIPUSH 3 // coloca o valor “3” no topo da pilha 7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha 9 BIPUSH 1 // coloca o valor “1” no topo da pilha
10 ISUB // coloca no topo da pilha a subtração “j-1” 11 ISTORE j // retira resultado do topo e coloca em j 12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
0
Estado da pilha de operandos: k
j i
Variáveis locais:
74
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha
2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k” 4 ISTORE i // retira resultado do topo e coloca em i 5 ILOAD i // copia a variável i para o topo da pilha 6 BIPUSH 3 // coloca o valor “3” no topo da pilha 7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha 9 BIPUSH 1 // coloca o valor “1” no topo da pilha 10 ISUB // coloca no topo da pilha a subtração “j-1” 11 ISTORE j // retira resultado do topo e coloca em j 12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
j
1
Estado da pilha de operandos: k
j i
75 Circuitos Digitais II – Prof. Marcos Zurita
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha
2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k” 4 ISTORE i // retira resultado do topo e coloca em i 5 ILOAD i // copia a variável i para o topo da pilha 6 BIPUSH 3 // coloca o valor “3” no topo da pilha 7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha 9 BIPUSH 1 // coloca o valor “1” no topo da pilha
10 ISUB // coloca no topo da pilha a subtração “j-1” 11 ISTORE j // retira resultado do topo e coloca em j 12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
k j
2
Estado da pilha de operandos: k
j i
Variáveis locais:
76
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha 2 ILOAD k // copia a variável k para o topo da pilha
3 IADD // coloca no topo da pilha a soma “j+k”
4 ISTORE i // retira resultado do topo e coloca em i 5 ILOAD i // copia a variável i para o topo da pilha 6 BIPUSH 3 // coloca o valor “3” no topo da pilha 7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha 9 BIPUSH 1 // coloca o valor “1” no topo da pilha 10 ISUB // coloca no topo da pilha a subtração “j-1” 11 ISTORE j // retira resultado do topo e coloca em j 12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
j + k
3
Estado da pilha de operandos: k
j i
77 Circuitos Digitais II – Prof. Marcos Zurita
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha 2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k”
4 ISTORE i // retira resultado do topo e coloca em i
5 ILOAD i // copia a variável i para o topo da pilha 6 BIPUSH 3 // coloca o valor “3” no topo da pilha 7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha 9 BIPUSH 1 // coloca o valor “1” no topo da pilha
10 ISUB // coloca no topo da pilha a subtração “j-1” 11 ISTORE j // retira resultado do topo e coloca em j 12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
4
Estado da pilha de operandos: k
j i
Variáveis locais:
78
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha 2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k” 4 ISTORE i // retira resultado do topo e coloca em i
5 ILOAD i // copia a variável i para o topo da pilha
6 BIPUSH 3 // coloca o valor “3” no topo da pilha 7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha 9 BIPUSH 1 // coloca o valor “1” no topo da pilha 10 ISUB // coloca no topo da pilha a subtração “j-1” 11 ISTORE j // retira resultado do topo e coloca em j 12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
i
5
Estado da pilha de operandos: k
j i
79 Circuitos Digitais II – Prof. Marcos Zurita
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha 2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k” 4 ISTORE i // retira resultado do topo e coloca em i 5 ILOAD i // copia a variável i para o topo da pilha
6 BIPUSH 3 // coloca o valor “3” no topo da pilha
7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha 9 BIPUSH 1 // coloca o valor “1” no topo da pilha
10 ISUB // coloca no topo da pilha a subtração “j-1” 11 ISTORE j // retira resultado do topo e coloca em j 12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
3 i
6
Estado da pilha de operandos: k
j i
Variáveis locais:
80
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha 2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k” 4 ISTORE i // retira resultado do topo e coloca em i 5 ILOAD i // copia a variável i para o topo da pilha 6 BIPUSH 3 // coloca o valor “3” no topo da pilha
7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha 9 BIPUSH 1 // coloca o valor “1” no topo da pilha 10 ISUB // coloca no topo da pilha a subtração “j-1” 11 ISTORE j // retira resultado do topo e coloca em j 12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
7
Estado da pilha de operandos: k
j i
81 Circuitos Digitais II – Prof. Marcos Zurita
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha 2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k” 4 ISTORE i // retira resultado do topo e coloca em i 5 ILOAD i // copia a variável i para o topo da pilha 6 BIPUSH 3 // coloca o valor “3” no topo da pilha 7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha
9 BIPUSH 1 // coloca o valor “1” no topo da pilha
10 ISUB // coloca no topo da pilha a subtração “j-1” 11 ISTORE j // retira resultado do topo e coloca em j 12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
j
8
Estado da pilha de operandos: k
j i
Variáveis locais:
82
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha 2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k” 4 ISTORE i // retira resultado do topo e coloca em i 5 ILOAD i // copia a variável i para o topo da pilha 6 BIPUSH 3 // coloca o valor “3” no topo da pilha 7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha
9 BIPUSH 1 // coloca o valor “1” no topo da pilha
10 ISUB // coloca no topo da pilha a subtração “j-1” 11 ISTORE j // retira resultado do topo e coloca em j 12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
1 j
9
Estado da pilha de operandos: k
j i
83 Circuitos Digitais II – Prof. Marcos Zurita
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha 2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k” 4 ISTORE i // retira resultado do topo e coloca em i 5 ILOAD i // copia a variável i para o topo da pilha 6 BIPUSH 3 // coloca o valor “3” no topo da pilha 7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha 9 BIPUSH 1 // coloca o valor “1” no topo da pilha
10 ISUB // coloca no topo da pilha a subtração “j-1”
11 ISTORE j // retira resultado do topo e coloca em j 12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
j-1
10
Estado da pilha de operandos: k
j i
Variáveis locais:
84
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha 2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k” 4 ISTORE i // retira resultado do topo e coloca em i 5 ILOAD i // copia a variável i para o topo da pilha 6 BIPUSH 3 // coloca o valor “3” no topo da pilha 7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha 9 BIPUSH 1 // coloca o valor “1” no topo da pilha 10 ISUB // coloca no topo da pilha a subtração “j-1”
11 ISTORE j // retira resultado do topo e coloca em j
12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
11
Estado da pilha de operandos: k
j i
85 Circuitos Digitais II – Prof. Marcos Zurita
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha 2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k” 4 ISTORE i // retira resultado do topo e coloca em i 5 ILOAD i // copia a variável i para o topo da pilha 6 BIPUSH 3 // coloca o valor “3” no topo da pilha 7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha 9 BIPUSH 1 // coloca o valor “1” no topo da pilha
10 ISUB // coloca no topo da pilha a subtração “j-1” 11 ISTORE j // retira resultado do topo e coloca em j
12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
12
Estado da pilha de operandos: k
j i
Variáveis locais:
86
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha 2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k” 4 ISTORE i // retira resultado do topo e coloca em i 5 ILOAD i // copia a variável i para o topo da pilha 6 BIPUSH 3 // coloca o valor “3” no topo da pilha 7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha 9 BIPUSH 1 // coloca o valor “1” no topo da pilha 10 ISUB // coloca no topo da pilha a subtração “j-1” 11 ISTORE j // retira resultado do topo e coloca em j 12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
0
13
Estado da pilha de operandos: k
j i
87 Circuitos Digitais II – Prof. Marcos Zurita
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha 2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k” 4 ISTORE i // retira resultado do topo e coloca em i 5 ILOAD i // copia a variável i para o topo da pilha 6 BIPUSH 3 // coloca o valor “3” no topo da pilha 7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha 9 BIPUSH 1 // coloca o valor “1” no topo da pilha
10 ISUB // coloca no topo da pilha a subtração “j-1” 11 ISTORE j // retira resultado do topo e coloca em j 12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k
15 L2: // não faz nada por um ciclo
14
Estado da pilha de operandos: k
j i
Variáveis locais:
88
Execução do um fragmento de código IJVM
1 ILOAD j // copia a variável j para o topo da pilha 2 ILOAD k // copia a variável k para o topo da pilha 3 IADD // coloca no topo da pilha a soma “j+k” 4 ISTORE i // retira resultado do topo e coloca em i 5 ILOAD i // copia a variável i para o topo da pilha 6 BIPUSH 3 // coloca o valor “3” no topo da pilha 7 IF_ICMPEQ L1 // desvia para “L1” se i=3
8 ILOAD j // copia a variável j para o topo da pilha 9 BIPUSH 1 // coloca o valor “1” no topo da pilha 10 ISUB // coloca no topo da pilha a subtração “j-1” 11 ISTORE j // retira resultado do topo e coloca em j 12 GOTO L2 // desvio incondicional para “L2”
13 L1: BIPUSH 0 // coloca o valor “0” no topo da pilha
14 ISTORE k // retira o valor “0” do topo e coloca em k 15 L2: // não faz nada por um ciclo
15
Estado da pilha de operandos: k
j i
89 Circuitos Digitais II – Prof. Marcos Zurita
Código hexadecimal gerado para cada instrução IJVM pelo programa montador
Linha Instrução IJVM OpcodeCódigo Hexa GeradoArg Arg
1 ILOAD j 0x15 0x02 2 ILOAD k 0x15 0x03 3 IADD 0x60 4 ISTORE i 0x36 0x01 5 ILOAD i 0x15 0x01 6 BIPUSH 3 0x10 0x03 7 IF_ICMPEQ L1 0x9F 0x00 0x0D 8 ILOAD j 0x15 0x02 9 BIPUSH 1 0x10 0x01 10 ISUB 0x64 11 ISTORE j 0x36 0x02 12 GOTO L2 0xA7 0x00 0x07 13 L1: BIPUSH 0 0x10 0x00 14 ISTORE k 0x36 0x03 15 L2: 0x00 k j i Variáveis locais: 90
ì Andrew S. Tanenbaum, “Organização
Estruturada de Computadores”, 5a Ed., Pearson, 2006.
ì J. L. Hennessy & D. A. Patterson, “Arquitetura
de Computadores - Uma Abordagem Quantitativa”, Editora Campus, 2003.
ì Willians Stallings, “Arquitetura e Organização
de Computadores”, 5ª Edição, Pearson, 2003.
ì Albert Paul Malvino, “Microcomputadores e
Microprocessadores”, McGraw-Hill, 1985.
ì Herbert Taub, “Circuitos Digitais e