Arquitectura de Computadores II
3º Ano
Máquinas Virtuais
João Luís Ferreira Sobral
Departamento do Informática
Universidade do Minho
Março 2003
Máquinas Virtuais
Questões que levaram à introdução de máquinas virtuais
1. Como possibilitar a execução de programas em arquitecturas de
computadores com conjuntos de instruções diferentes, sem efectuar a
recompilação do código fonte?
2. Como garantir que código executável que é descarregado é seguro?
3. Como produzir código compacto, por forma a que seja descarregado
rapidamente?
1. Obtenção de código executável portável (sem recompilação das fontes)
•
O código fonte é compilado para um ISA virtual (ISA da máquina virtual),
que durante a execução é traduzido para um ISA real
•
As E/S são efectuadas através de chamadas a rotinas pré-definidas (i.é., não
existem instruções específicas para E/S)
•
A abordagem tradicional obriga ao desenvolvimento de nº Linguagens x nº
de arquitecturas compiladores. Com uma máquina virtual não apenas
necessários nº Linguagens compiladores + nº de arq. máquinas virtuais
2. Segurança do código executável
•
O código executável é validado durante a execução ou quando carregado
•
Cada operando tem um tipo associado possibilitando validações adicionais
3. Código compacto
•
Utilizar um ISA que origine instruções com um número reduzido de bits
Exemplos de Máquinas Virtuais
•
Smalltalk – Digitalk (década de 80)
•
JVM (Java Virtual Machine) – SUN (meados de 90)
•
CLR (Common Language Runtime) – Microsoft (finais de 90)
Arquitectura de Computadores II
2
© João Luís Sobral 2003
Java Virtual Machine
Visão global
•
Máquina de stack (todos os cálculos são efectuados numa pilha)
•
Opcodes de 8 bits (201 definidos, 25 quick, 3 reservados).
•
Grande parte das instruções ocupa apenas 8 bits.
•
Cada instrução identifica o tipo de dados dos operandos, o que melhora
a segurança do código
•
Instruções para acesso a elementos de arrays
•
Zona dedicada ao armazenamento de constantes e símbolos
•
Não existem instruções para manipulação directa de endereços de
memória (segurança do código!)
Tipos de dados
•
•
•
•
•
•
•
•
byte – 8 bits em complemento para 2
short - 16 bits em complemento para 2
int - 32 bits em complemento para 2
long – 64 bits em complemento para 2
char – 16 bits inteiros sem sinal representando caracteres Unicode
float – 32 bits IEEE 754 em vírgula flutuante
double – 64 bits IEEE 754 em vírgula flutuante
reference – referência para um array ou objecto
Zonas de dados
•
PC – registo que aponta para a instrução em execução
•
Java stack – equivalente à pilha nas linguagens convencionais, contém
os parâmetros dos métodos, as variáveis locais e os resultados
intermédios
•
Heap – contém objectos e arrays
•
Área de métodos – contém código dos métodos
•
Área de constantes – contém as constantes utilizadas em cada classe e
as referências a símbolos externos (semelhante a uma tabela de
símbolos, mas com um âmbito alargado)
Arquitectura de Computadores II
3
© João Luís Sobral 2003
Java Virtual Machine
Conjunto de Instruções
•
Cada instrução é constituída por um opcode de 8 bits seguido de um ou
mais operandos
•
O conjunto de instruções não é ortogonal: algumas instruções operam
apenas em operandos específicos
•
Cada instrução é precedida da indicação dos tipos dos operandos
•
A stack frame de cada método contém:
•
•
•
As instruções máquina podem-se referir aos seguintes operandos:
1.
2.
3.
4.
5.
•
Grupo
Transferência
de
informação
Aritméticas
Lógicas e
Deslocamento
Comparação
e salto
Outras
Variáveis locais, numeradas de 0, 1, 2, ...
Uma pilha para manipular os dados, que se encontra vazia
quando um método inicia
valor imediato (imm)
variável local (#loc)
a pilha
a zona de constantes (#cons)
endereço de salto (end)
Quadro resumo das instruções:
Tipos de
Operandos
Instrução
bipush imm8
sipush imm16
Tconst_n
ldc
#cons8
pop, dup, swap
Tload, Tstore
#loc8
Tload_<n>, Tstore_<n>
Taload, Tastore
getfield, putfield #cons16
Tadd, Tsub, Tmult, Tdiv,
Trem, Tneg
Tinc #loc8 Imm8
Tand, Tor, Txor
Tshl, Tshr, Tushr
ifcond end16
if_icmp<cond> end16
goto end16
goto_w end32
invokestatic #cons16
Treturn
return
wide
new #cons16
newarray type8
Arquitectura de Computadores II
i, l, f, d, a
i, l, f, d, a
i, l, f, d, a
b, s, i, l, f, d, c, a
i, l, f, d
i
i, l
i, l
cond = eq | ne |
lt | le | gt | ge
i, l, f, d, a
4
#
Comentário
2
3
1
2
1
2
1
1
3
1
push immediate
push immediate
push constant 0 or 1
push item from constant pool
direct operand stack manipulation
load/store type T local variable #loc
load/store type T local variable n (0..3)
load/store array element of type T
load/store object field
addition, subtract, multiply, divide,
remainder, NEG
increment local var. by Imm8
AND, OR, XOR
shift left logical., right logical, right arth.
branch to PC + end16 if condz is true
branch to PC + end16 if cond is true
branch to PC + end16
branch to PC + end32
invoke static method #cons16
return value of type T from method
return from void method
gain access to more local variables
create new object
create new array of type
3
1
1
3
3
3
5
3
1
1
3
3
2
© João Luís Sobral 2003
Java Virtual Machine
Conjunto de Instruções (exemplos)
•
int x = 2
iconst_2
istore_0
•
int y = 6
bipush 6
istore_1
•
push byte 6
store into local var #1 (y)
int u = x + y
iload_0
iload_1
iadd
istore_2
•
push 2
store into local var #0 (x)
push x
push y
add
local #2 (v)
u = add(x,y,-1)
iload_0
iload_1
iconst_m1
invokestatic #1
istore_2
•
push
push
x >=
push
x
x
2
2 ?
0
int w[] = new int[3];
iconst_3
newarray int
astore_0
•
push a
push b
a + b
push c
(a + b) + c
return integer on stack
if ( x < 2 ) x=0;
iload_0
iconst_2
if_icmpge fim
iconst_0
istore_0
•
push x
push y
push -1
constant #1 = referência método add
get result from stack
static add(int a, int b,int c) { return(a+b+c); }
iload_0
iload_1
iadd
iload_2
iadd
ireturn
•
// static add(int,int,int)
push 3
w= int[3]
w[2] = 4;
aload_0
iconst_2
iconst_4
iastore
Arquitectura de Computadores II
push w
push 2
push 4
5
© João Luís Sobral 2003
Java Virtual Machine
Exercícios
Para cada uma das alíneas seguintes, verifique qual o código gerado pelo compilador
1. Expressões aritméticas
a. constantes
public class Main {
public static void main(String[] str) {
int x = 2;
int y = 6;
int z = 200;
int u = 2000000;
}
b. cálculos
z = x + y;
z = 3*((x/y) - 2/(z+u));
x++;
y <<= 3
2. Invocações de métodos e passagem de parâmetros
a. codificação de invocações de métodos
static add(int a, int b,int c) {
return(a + b + c);
}
public static void main(String[] str) {
....
add(x,y,-1);
}
b. codificação de métodos
interprete a informação apresentada com a assinatura do método add
3. Controlo de fluxo
if ( x < 2 ) x=0;
boolean flag = ( x < y);
for (int i=0; i<10; i++) x++;
4. Arrays
int w[] = new int[3];
w[2] = 4;
w[0]=w[2];
Arquitectura de Computadores II
6
© João Luís Sobral 2003
Download

Máquinas Virtuais - Universidade do Minho