Capítulo 2 - DEInfo

Propaganda
Arquitetura e Organização
de Computadores
Capítulo 2 – Conjunto de Instruções
• Material adaptado de:
Patterson e Henessy,
Computer Organization and Design 4th Edition
2
André Aziz ([email protected])
21/11/2013
• É o repertório de instruções de um computador;
• Computadores diferentes possuem conjuntos de
instruções diferentes:
• Mas em muitos aspectos eles são comuns;
• Computadores antigos tinham conjuntos de instruções
bem simples:
• Implementação simplificada;
• Muitos computadores modernos também possuem
conjunto de instruções simplificados.
Conjunto de Instruções - ISA
André Aziz ([email protected])
3
21/11/2013
• Usado como exemplo durante este curso;
• Stanford MIPS comercializado pelo MIPS Technologies
(www.mips.com);
• Grande parte do mercado de sistemas embarcados:
• Aplicações em Consumer Eletronics, Network/Storage,
equipamentos, câmeras, impressoras, ...
• Típico de muitos ISAs modernos:
• Vejam MIPS Reference Data.
MIPS Instruction Set
André Aziz ([email protected])
4
21/11/2013
• Todo computador deve ser capaz de executar operações
aritméticas:
• Notação da MIPS Assembly Language:
add a, b, c
instrui o computado a adicionar duas variáveis b e c e
colocar o resultado da soma em a:
a=b+c
Operações Aritméticas
André Aziz ([email protected])
5
21/11/2013
• Essa notação é fixa, ou seja, sem variações.
• Se você quiser fazer ...
a=b+c+d+e
então é necessário...
add a, b, c
add a, a, d
add a, a, e
# The sum of b and c is placed in a.
# The sum of b, c, and d is now in a.
# The sum of b, c, d, and e is now in a.
Operações Aritméticas
André Aziz ([email protected])
6
21/11/2013
• “Simplicidade favorece a regularidade”;
• Todas as operações aritméticas possuim o mesmo
formato;
• Regularidade faz implementação mais simples;
• Simplicidade permite alto desempenho a um baixo custo.
Princípio de Projeto 1
André Aziz ([email protected])
7
21/11/2013
• Código C:
f = (g + h) - (i + j);
• Código compilado do MIPS:
add t0, g, h
add t1, i, j
sub f, t0, t1
# temp t0 = g + h
# temp t1 = i + j
# f = t0 - t1
Exemplo: Operações
aritméticas
André Aziz ([email protected])
8
21/11/2013
• Instruções aritméticas usam operandos que vem de
registradores;
• MIPS possui 32 x32-bit registradores (banco de
registradores):
• Usado para dados que são frequentemente utilizados;
• Numerados de 0 a 31;
• 32-bit de dados é chamado de “word”;
• Nomes dos registradores:
• $t0, $t1, ..., $t9 para dados temporários (variáveis do
compilador);
• $s0, $s1, ..., $s7 para dados não-temporários (variáveis do
programador).
Operandos em registradores
André Aziz ([email protected])
9
21/11/2013
• “Menor é mais rápido”;
• Um número grande de registradores pode aumentar o
tempo do ciclo de clock, tornando o sistema lento.
Princípio de Projeto 2
André Aziz ([email protected])
10
21/11/2013
• Código C:
f = (g + h) - (i + j);
• f, …, j in $s0, …, $s4
• Código compilado do MIPS:
add $t0, $s1, $s2
add $t1, $s3, $s4
sub $s0, $t0, $t1
Exemplo: Operandos em
registradores
André Aziz ([email protected])
11
21/11/2013
• Linguagens de programação possuem variáveis que
contem dados simples, mas eles também tem estruturas
de dados mais complexas (arrays e structures):
• Podem conter mais dados do que o número de registradores
em um computador.
Como computadores podem
representar e acessar grandes
estruturas de dados?
André Aziz ([email protected])
12
21/11/2013
• Memória principal é usada para dados compostos:
• Arrays, structures, dynamic data;
• Para realizar operações aritméticas:
• Carregar valores da memória em registadores;
• Armazenar resultados do registrador na memória.
• Memória é endereçada a bytes:
• Cada endereço identifica unicamente um byte.
Operandos na Memória
André Aziz ([email protected])
13
21/11/2013
• “Words” são alinhadas na memória:
• Endereços tem que ser múltiplo de 4 (4 Bytes => 32 bits);
• MIPS é Big Endian:
• Byte mais significativo está no menor endereço da palavra;
• OBS: Little Endian; Byte menos significativo está no menor
endereço da palavra.
Operandos na memória
André Aziz ([email protected])
14
21/11/2013
• Memória é um grande unidimensional array com o
endereço atuando como índice deste array;
• Inicia em 0.
OBS: O que é a memória?
André Aziz ([email protected])
15
21/11/2013
• A instrução que copia dados da memória para os
registradores é tradicionalmente chamada de load;
• A que faz a operação inversa é chamada de store;
• A instrução de load é composta pelo registrador destino,
uma constante e registrador de base:
• A soma da constante com o registrador base é utilizado para
acessar a memória;
• Instrução do MIPS é lw (load word).
Carregar dados da memória
André Aziz ([email protected])
16
21/11/2013
• Código C:
g = h + A[8];
• g in $s1, h in $s2, base address of A in $s3
• Código compilado do MIPS:
• Índice 8 requer um deslocamento (offset) de 32
• 4 bytes por word
lw $t0, 32($s3) # load word
add $s1, $s2, $t0
offset
base register
Exemplo 1: Operandos na
memória
André Aziz ([email protected])
17
21/11/2013
• Código C:
A[12] = h + A[8];
• h está em $s2, endereço base de A está em $s3
• Código compilado para o MIPS:
• Índice 8 requer um deslocamento (offset) de 32
• Índice 12 requer um deslocamento (offset) de 48
lw $t0, 32($s3) # load word
add $t0, $s2, $t0
sw $t0, 48($s3) # store word
Exemplo 2: Operandos na
memória
André Aziz ([email protected])
18
21/11/2013
• São constantes especificadas em uma instrução:
addi $s3, $s3, 4
• Não possui instrução de subtração com imediato:
• Usar constantes negativas:
addi $s2, $s1, -1
Operandos Imediatos
André Aziz ([email protected])
19
21/11/2013
• “Faça o caso comum mais rápido”
• Pequenas constantes são comuns ao programas;
• Operando imediato evita instruções de load.
Princípio de Projeto 3
André Aziz ([email protected])
20
21/11/2013
• O registrador 0 ($zero) é a constante 0:
• Não pode ser sobrescrito;
• Útil para operações comuns:
• Ex: mover dados entre registradores:
add $t2, $s1, $zero
# move $s1 para $t2
A constante Zero
André Aziz ([email protected])
21
21/11/2013
NÚMEROS INTEIROS COM
OU SEM SINAL
22
André Aziz ([email protected])
21/11/2013
• Dado um número de n-bits:
n

1
n

2
x

x
2
x
2


x
2

x
2
n

1
n

2
0
1
1
0
• Alcance: 0 até 2n-1
• Exemplo:
• 0000 0000 0000 0000 0000 0000 0000 10112
= 0 + … + 1×23 + 0×22 +1×21 +1×20
= 0 + … + 8 + 0 + 2 + 1 = 1110
• Para 32 bits:
• 0 até +4.294.967.295
Números Inteiros Binários
sem Sinal
André Aziz ([email protected])
23
21/11/2013
• Dado um número de n-bits:
n

1
n

2
1
0
x


x
2

x
2



x
2

x
2
n

1
n

2
1
0
• Alcance: -2n-1 até 2n-1 – 1
• Exemplo:
• 1111 1111 1111 1111 1111 1111 1111 11002
= –1×231 + 1×230 + … + 1×22 +0×21 +0×20
= –2,147,483,648 + 2,147,483,644 = –410
• Para 32 bits:
• -2.147.483.648 até +2.147.483.647
Inteiros em Complemento a
2 com Sinal
André Aziz ([email protected])
24
21/11/2013
• Bit 31 é o bit de sinal:
• 1 para números negativo;
• 0 para não números não-negativos;
• -(-2n-1) não pode ser representado;
• Números não-negativos tem a mesma representação em inteiros sem
sinal e em complemento a dois;
• Alguns números específicos:
• 0: 0000 0000 … 0000
• –1: 1111 1111 … 1111
• Mais-negativo:
1000 0000 … 0000
• Mais-positivo:
0111 1111 … 1111
Inteiros em Complemento a
2 com Sinal
André Aziz ([email protected])
25
21/11/2013
• Complemento dos bits somados a 1:
• Complemento significa: 1 → 0, 0 → 1
xx
1
1
1
1
...1
1
1

1
2
x
1

x
• Exemplo: negar +2
• +2 = 0000 0000 … 00102
• –2 = 1111 1111 … 11012 + 1
= 1111 1111 … 11102
Negação com Sinal
André Aziz ([email protected])
26
21/11/2013
• Representando um número utilizando mais bits:
• Preservar o valor numérico;
• No ISA do MIPS:
• addi: estende o valor do imediato;
• lb, lh: estende o valor do byte/halfword carregados;
• beq, bne: estente o valor do deslocamento;
• Replicar o valor do sinal para esquerda:
• Valores sem sinal: sempre estender com 0s;
• Exemplo: 8-bit para 16-bit
• +2: 0000 0010 => 0000 0000 0000 0010
• –2: 1111 1110 => 1111 1111 1111 1110
Extensão de Sinal
André Aziz ([email protected])
27
21/11/2013
REPRESENTANDO
INSTRUÇÕES
28
André Aziz ([email protected])
21/11/2013
• Instruções são codificadas em binário (números):
• Chamado de código de máquina:
• Instruções do MIPS:
• Codificadas como palavras de 32-bits;
• Um pequeno número de formatos codificam o código da
operação (opcode), números dos registadores, ...
• Regularidade!
• Números dos registradores:
• $t0 - $t7 são os registradores números 8 – 15;
• $t8 - $t9 são os registradores números 24 – 25;
• $s0 - $s7 são os registradores números 16 – 23;
Representação de uma
instrução
André Aziz ([email protected])
29
21/11/2013
op
rs
rt
rd
shamt
funct
6 bits
5 bits
5 bits
5 bits
5 bits
6 bits
• Campos da instrução:
•
•
•
•
•
•
op: código da operação (opcode);
rs: número do primeiro registrador fonte;
rt: número do segundo registrador fonte;
rd: número do registrador de destino;
shamt: quantidade de shifs (00000 por enquanto);
funct: código da função (estende o opcode).
Instruções do formato R
André Aziz ([email protected])
30
21/11/2013
op
rs
rt
rd
shamt
funct
6 bits
5 bits
5 bits
5 bits
5 bits
6 bits
• add $t0, $s1, $s2
special
$s1
$s2
$t0
0
add
0
17
18
8
0
32
000000
10001
10010
01000
00000
100000
000000100011001001000000001000002 = 0232402016
Exemplo do formato R
André Aziz ([email protected])
31
21/11/2013
• Base 16:
• Representação compacta de cadeias de bits;
• 4 bits por cada dígito hexadecimal;
• Example: eca8 6420
• 1110 1100 1010 1000 0110 0100 0010 0000
Hexadecimal
André Aziz ([email protected])
32
21/11/2013
op
rs
rt
constant or address
6 bits
5 bits
5 bits
16 bits
• Operações aritméticas com imediatos e instruções de
load/store:
• rt: número do registrador destino ou fonte;
• Constante: -215 até +215-1;
• Endereço: deslocamento (offset) adicionado ao registrador
base rs;
Instruções do formato I
André Aziz ([email protected])
33
21/11/2013
• “Bons projetos demandam bons compromissos”;
• Diferentes formatos complicam a decodificação das
instruções, mas permite instruções do mesmo tamanho;
• Mantenha os formatos das instruções o mais similar
possível:
• R-type (para registradores) ou R-format.
• I-type (para imediatos) ou I-format.
Princípio de Projeto 4
André Aziz ([email protected])
34
21/11/2013
• Se $t1 tem o endereço base do array A e $s2 corresponde
ao, então a sentença:
é compilada para:
lw
add
sw
$t0,1200($t1)
$t0,$s2,$t0
$t0,1200($t1)
A[300] = h + A[300];
# Temporary reg $t0 gets A[300]
# Temporary reg $t0 gets h + A[300]
# Stores h + A[300] back into A[300]
• Qual é o código de máquina para essas três instruções?
Exemplo: Traduzindo Assembly para
código de máquina
André Aziz ([email protected])
35
21/11/2013
The BIG Picture
• Instruções são representados
em binários, como os dados;
• Instruções e dados são
armazenados na memória;
• Programas podem operar
sobre programas;
• Compatibilidade binária
permite programas
funcionarem em diferentes
computadores
• ISAs padronizados.
Computadores com
programas armazenados
André Aziz ([email protected])
36
21/11/2013
OPERAÇÕES LÓGICAS
37
André Aziz ([email protected])
21/11/2013
• Instruções para manipulação da cadeia de bits:
• Útil para extração ou inserção de grupos de bits em uma
palavra.
Operações Lógicas
André Aziz ([email protected])
38
21/11/2013
op
rs
rt
rd
shamt
funct
6 bits
5 bits
5 bits
5 bits
5 bits
6 bits
• Desloca a cadeia de bits para esquerda ou direita;
• shamt: número de bits para deslocar;
• Shift Left Logical (sll):
• Desloca para esquerda e preenche com zeros no final;
• sll de i-bits multiplica a palavra por 2i;
• Shift Right Logical (srl):
• Desloca para direita e preenche com zeros no início;
• srl de i-bits divide a palavra por 2i (só para números sem
sinal).
Operações de shift
André Aziz ([email protected])
39
21/11/2013
• Útil para mascarar bits em uma palavra:
• Selecionar alguns bits, limpando os outros com 0;
and $t0, $t1, $t2
$t2
0000 0000 0000 0000 0000 1101 1100 0000
$t1
0000 0000 0000 0000 0011 1100 0000 0000
$t0
0000 0000 0000 0000 0000 1100 0000 0000
Operações de AND
André Aziz ([email protected])
40
21/11/2013
• Útil para incluir bits em uma palavra:
• Seta alguns bits para 1 sem mudar os outros;
or $t0,$t1, $t2
$t2
0000 0000 0000 0000 0000 1101 1100 0000
$t1
0000 0000 0000 0000 0011 1100 0000 0000
$t0
0000 0000 0000 0000 0011 1101 1100 0000
Operações de OR
André Aziz ([email protected])
41
21/11/2013
• Útil para inverter bits em uma palavra:
• Muda 0 para 1, e 1 para 0;
• MIPS tem uma operação de NOR com 3 operandos:
• a NOR b == NOT (a OR b)
nor $t0, $t1, $zero
Register 0: always
read as zero
$t1
0000 0000 0000 0000 0011 1100 0000 0000
$t0
1111 1111 1111 1111 1100 0011 1111 1111
Operações de NOT
André Aziz ([email protected])
42
21/11/2013
INSTRUÇÕES PARA TOMAR
DECISÕES
43
André Aziz ([email protected])
21/11/2013
• O que diferencia um computador de uma calculadora
simples é a habilidade de tomar decisões;
• A tomada de decisão é representada em linguagens de
programação através das sentenças de if, algumas vezes
combinadas com sentenças de go to e rótulos (labels).
O diferencial do computador
André Aziz ([email protected])
44
21/11/2013
• Desvia (branch) para um rótulo se a condição da
instrução for verdadeiro:
• Caso contrário, continua sequencialmente;
• beq rs, rt, L1
• Se (rs == rt) então desvia para a instrução rotulada de L1;
• bne rs, rt, L1
• Se (rs != rt) então desvia para a instrução rotulada de L1;
• j L1
• Pulo (jump) incondicional para a instrução rotulada de L1.
Operações condicionais
André Aziz ([email protected])
45
21/11/2013
• Código C:
if (i==j) f = g+h;
else f = g-h;
• f, g, … em $s0, $s1, …
• Código compilado do MIPS:
bne $s3, $s4, Else
add $s0, $s1, $s2
j
Exit
Else: sub $s0, $s1, $s2
Exit: …
Assembler calculates addresses
Exemplo: Compilando
sentenças if
André Aziz ([email protected])
46
21/11/2013
• Código C:
while (save[i] == k) i += 1;
• i em $s3, k em $s5, endereço base do save está $s6
• Código compilado do MIPS:
Loop: sll
add
lw
bne
addi
j
Exit: …
$t1,
$t1,
$t0,
$t0,
$s3,
Loop
$s3, 2
$t1, $s6
0($t1)
$s5, Exit
$s3, 1
Exemplo: Compilando
sentenças de Loop
André Aziz ([email protected])
47
21/11/2013
• Um bloco básico é uma sequência de instruções com:
• Nenhuma instrução de desvio (exceto no final)
• Nenhum alvo de uma instrução de desvio (exceto no
começo)
• Um compilador identifica blocos
básicos para otimizações;
• Um processador avançado pode
acelerar a execução de um bloco
básico.
Blocos básicos
André Aziz ([email protected])
48
21/11/2013
• Seta o resultado para 1 se a condição é verdadeira:
• Caso contrário, seta para 0;
• slt rd, rs, rt
• Se (rs < rt) então rd = 1, caso contrário rd = 0;
• slti rt, rs, constante
• Se (rs < constante) então rt = 1, caso contrário rt = 0;
• Usado em combinação com beq, bne:
• slt $t0, $s1, $s2
bne $t0, $zero, L
# if ($s1 < $s2)
#
branch to L
Mais operações condicionais
André Aziz ([email protected])
49
21/11/2013
• Por que não blt, bge, etc?
• Hardware para <, ≥, … é mais lento que =, ≠
• Combinando isso com o branch em si envolve mais trabalho
por instrução, levando um clock mais lento;
• Todas as intruções seriam penalizadas!
• beq e bne são os casos mais comuns;
• Este é um bom compromisso de projeto (princípio 4);
Projeto das instruções de
desvio
André Aziz ([email protected])
50
21/11/2013
• Comparação com sinal: slt, slti
• Comparação sem sinal: sltu, sltui
• Exemplo:
• $s0 = 1111 1111 1111 1111 1111 1111 1111 1111
• $s1 = 0000 0000 0000 0000 0000 0000 0000 0001
• slt
$t0, $s0, $s1
# signed
• –1 < +1  $t0 = 1
• sltu $t0, $s0, $s1
# unsigned
• +4,294,967,295 > +1  $t0 = 0
Sinal vs. Sem sinal
André Aziz ([email protected])
51
21/11/2013
CHAMADA DE
PROCEDIMENTOS
52
André Aziz ([email protected])
21/11/2013
• Passos de uma chamada de procedimento:
1. Colocar parâmetros nos registradores;
2. Transferir o controle para o procedimento;
3. Adquirir espaço de armazenamento para o
procedimento;
4. Executar as operações do procedimento;
5. Colocar o resultado em um registrador para quem
chamou o procedimento;
6. Retornar para o local da chamada.
Chamada de procedimento
André Aziz ([email protected])
53
21/11/2013
• $a0 – $a3: parâmetros (reg’s 4 – 7);
• $v0, $v1: retorno (reg’s 2 e 3);
• $t0 – $t9: temporários:
• Podem ser sobrescritos pelo procedimento;
• $s0 – $s7: “salvos” ou globais:
• Devem ser salvos/recuperados pelo procedimento;
•
•
•
•
$gp: Ponteiro global para dados estáticos (reg 28);
$sp: Ponteiro da pilha (stack pointer) (reg 29);
$fp: Ponteiro da janela (frame pointer) (reg 30);
$ra: Endereço para retorno do procedimento (reg 31).
Convenção: Uso de
registradores
André Aziz ([email protected])
54
21/11/2013
• Chamada de procedimento: jump and link (pular e
conectar):
jal <rótulo>
• Salva o endereço da instrução seguinte ao jal no $ra (link);
• Pula para o endereço alvo (rótulo);
• Retorno de procedimento: jump register (pular para o
registrador):
jr $ra
• Copia $ra no contador de programa;
Instruções para chamar
procedimentos
André Aziz ([email protected])
55
21/11/2013
• C code:
int leaf_exemple (int g, h, i, j)
{
int f;
f = (g + h) - (i + j);
return f;
}
• Parâmetros g, …, j em $a0, …, $a3
• f em $s0 (obriga a salvar $s0 na pilha)
• Resultado em $v0
Exemplo: Chamada de
procedimento “folha”
André Aziz ([email protected])
56
21/11/2013
• Código MIPS:
leaf_example:
addi $sp, $sp, -4
sw
$s0, 0($sp)
add $t0, $a0, $a1
add $t1, $a2, $a3
sub $s0, $t0, $t1
add $v0, $s0, $zero
lw
$s0, 0($sp)
addi $sp, $sp, 4
jr
$ra
Exemplo: Chamada de
procedimento “folha”
André Aziz ([email protected])
Save $s0 on stack
Procedure body
Result
Restore $s0
Return
57
21/11/2013
• Procedimentos que chamam outros procedimentos;
• Para uma chamada aninhada, os procedimentos devem
salvar na pilha:
• O seu endereço de retorno;
• Quaisquer parâmetros e temporários que serão necessários
após a chamada do outro procedimento;
• Retirar dados da pilha após a chamada.
Procedimentos não-”folha”
André Aziz ([email protected])
58
21/11/2013
• Código C:
int fact (int n)
{
if (n < 1) return f;
else return n * fact(n - 1);
}
• Parâmetros em $a0
• Resultado em $v0
Exemplo: Procedimento não”folha”
André Aziz ([email protected])
59
21/11/2013
• Código MIPS:
fact:
addi
sw
sw
slti
beq
addi
addi
jr
L1: addi
jal
lw
lw
addi
mul
jr
$sp,
$ra,
$a0,
$t0,
$t0,
$v0,
$sp,
$ra
$a0,
fact
$a0,
$ra,
$sp,
$v0,
$ra
$sp, -8
4($sp)
0($sp)
$a0, 1
$zero, L1
$zero, 1
$sp, 8
$a0, -1
0($sp)
4($sp)
$sp, 8
$a0, $v0
André Aziz ([email protected])
#
#
#
#
adjust stack for 2 items
save return address
save argument
test for n < 1
#
#
#
#
#
#
#
#
#
#
if so, result is 1
pop 2 items from stack
and return
else decrement n
recursive call
restore original n
and return address
pop 2 items from stack
multiply to get result
and return
60
21/11/2013
ORGANIZAÇÃO DA MEMÓRIA
61
André Aziz ([email protected])
21/11/2013
• Variáveis locais armazenadas pelo procedimento;
• Janela do procedimento (frame):
• Usado por alguns compiladores para gerenciar o
armazenamento na pilha
Dados locais na pilha
André Aziz ([email protected])
62
21/11/2013
• Text: código do programa;
• Static Data: variáveis globais:
• Ex. variáveis estáticas em C, arrays
constantes e strings;
• $gp inicializado para tratar
endereços nesse segmento;
• Dynamic Data: heap:
• Ex. “malloc” em C, “new” em Java;
• Stack: armazenamento automático;
Layout da Memória
André Aziz ([email protected])
63
21/11/2013
MANIPULANDO DADOS
64
André Aziz ([email protected])
21/11/2013
• Conjunto de caracteres codificados em bytes:
• ASCII: 128 caracteres:
• 95 gráficos, 33 de controle;
• Latin-1: 256 caracteres:
• ASCII. +96 caracteres gráficos;
• Unicode: conjunto de caracteres de 32 bits:
• Usado em Java, C++, ...
• Maioria dos alfabetos mundiais, mais símbolos;
• UTF-8, UTF-16: tamanhos variáveis de codificação.
Caracteres
André Aziz ([email protected])
65
21/11/2013
• Load/store byte/halfword instruções do MIPS:
• Utilizado principalmente para trabalhar com strings;
• lb rt, offset(rs)
lh rt, offset(rs)
• Estende o sinal para 32 bits em rt
• lbu rt, offset(rs)
lhu rt, offset(rs)
• Estende zero para 32 bits em rt
• sb rt, offset(rs)
sh rt, offset(rs)
• Escreve o byte/halfword mais a direita de rt na memória.
Operações com byte e
meia-palavra
André Aziz ([email protected])
66
21/11/2013
• Código C:
• String terminada em NULL;
void strcpy (char x[], char y[])
{ int i;
i = 0;
while ((x[i]=y[i])!='\0')
i += 1;
}
• Endereços de x, y em $a0, $a1;
• i em $s0.
Exemplo: Copiar String
André Aziz ([email protected])
67
21/11/2013
• MIPS code:
strcpy:
addi
sw
add
L1: add
lbu
add
sb
beq
addi
j
L2: lw
addi
jr
$sp,
$s0,
$s0,
$t1,
$t2,
$t3,
$t2,
$t2,
$s0,
L1
$s0,
$sp,
$ra
$sp, -4
0($sp)
$zero, $zero
$s0, $a1
0($t1)
$s0, $a0
0($t3)
$zero, L2
$s0, 1
0($sp)
$sp, 4
#
#
#
#
#
#
#
#
#
#
#
#
#
adjust stack for 1 item
save $s0
i = 0
addr of y[i] in $t1
$t2 = y[i]
addr of x[i] in $t3
x[i] = y[i]
exit loop if y[i] == 0
i = i + 1
next iteration of loop
restore saved $s0
pop 1 item from stack
and return
Exemplo: Copiar String
André Aziz ([email protected])
68
21/11/2013
• Maioria das constantes são pequenas:
• Imediato de 16-bits é suficiente;
• Para uma constante ocasional de 32-bits:
lui rt, constant
• Copia constante de 16 bits para a parte mais significativa do
rt
• Zera os 16 bits menos significativos.
lhi $s0, 61
0000 0000 0111 1101 0000 0000 0000 0000
ori $s0, $s0, 2304 0000 0000 0111 1101 0000 1001 0000 0000
Constantes de 32-bits
André Aziz ([email protected])
69
21/11/2013
ENDEREÇAMENTO DE
DESVIOS
70
André Aziz ([email protected])
21/11/2013
• As instruções de desvio especificam:
• Opcode, dois registradores, endereço alvo;
• Maioria dos desvios são desvios curtos:
• Para cima ou para baixo:
op
rs
rt
constant or address
6 bits
5 bits
5 bits
16 bits
• Endereçamento relativo ao contador de programa (PC):
• Endereço Alvo = PC + (offset x 4);
• OBS: PC já incrementado de 4.
Endereçamento de desvios
condicionais (branch)
André Aziz ([email protected])
71
21/11/2013
• Os alvos da instruções de jump (j e jal) podem ser
qualquer lugar no segmento de texto:
• O endereço alvo vem codificado na instrução:
op
address
6 bits
26 bits
• (Pseudo) endereçamento direto:
• Endereço Alvo = PC31...28 : (address x 4)
Concatenação
Endereçamento de desvios
incodicionais (jump)
André Aziz ([email protected])
72
21/11/2013
• Código de um loop de um exemplo anterior:
• Assuma que o loop está localizado a partir do endereço
80000:
Loop: sll
$t1, $s3, 2
80000
0
0
19
9
4
0
add
$t1, $t1, $s6
80004
0
9
22
9
0
32
lw
$t0, 0($t1)
80008
35
9
8
0
bne
$t0, $s5, Exit 80012
5
8
21
2
19
19
1
addi $s3, $s3, 1
80016
8
j
80020
2
Loop
Exit: …
80024
Exemplo: Endereçamento alvo
André Aziz ([email protected])
20000
73
21/11/2013
• Se o alvo de um branch é um rótulo muito distante para
ser codificado em 16 bits, então o Assembler reescreve o
código da seguinte forma:
• Exemplo:
L2:
beq $s0,$s1, L1
↓
bne $s0,$s1, L2
j L1
…
Desvios condicionais para
áreas distantes
André Aziz ([email protected])
74
21/11/2013
Resumo dos modos de
endereçamento
André Aziz ([email protected])
75
21/11/2013
SINCRONIZAÇÃO
76
André Aziz ([email protected])
21/11/2013
• Dois processadores compartilhando ao mesma região de
memória:
• P1 escreve, então P2 lê;
• Condição de corrida de P1 e P2 não sincronizarem:
• Resultado vai depender da ordem dos acessos;
• Necessário suporte de hardware:
• Operação atômica de leitura/escrita na memória;
• Ninguém acessa o dado entre a leitura e a escrita;
• Pode ser uma instrução única:
• Ex. swap atômico entre registrador e memória;
• Ou um par de instruções atômicas.
Sincronização
André Aziz ([email protected])
77
21/11/2013
• Load Linked: ll rt, offset(rs)
• Store Conditional: sc rt, offset(rs)
• Sucesso se o endereço não mudou desde o ll:
• Retorna 1 em rt;
• Falha se o endereço mudou:
• Retorna 0 em rt;
Sincronização no MIPS
André Aziz ([email protected])
78
21/11/2013
• Swap atômico (test/set lock)
try: add
ll
sc
beq
add
$t0,$zero,$s4
$t1,0($s1)
$t0,0($s1)
$t0,$zero,try
$s4,$zero,$t1
;copy exchange value
;load linked
;store conditional
;branch store fails
;put load value in $s4
Exemplo: Swap atômico
André Aziz ([email protected])
79
21/11/2013
TRADUÇÃO E INICIALIZAÇÃO
80
André Aziz ([email protected])
21/11/2013
Many compilers produce
object modules directly
Static linking
Tradução e Inicialização
André Aziz ([email protected])
81
21/11/2013
• Maioria das instruções do Assembler representam instruções
de máquina de uma-para-um;
• Pseudoinstruções: fruto da imaginação do Assembler:
move $t0, $t1
blt $t0, $t1, L
→ add $t0, $zero, $t1
→ slt $at, $t0, $t1
bne $at, $zero, L
• $at (register 1): assembler temporary
Pseudoinstruções
André Aziz ([email protected])
82
21/11/2013
• Provê informações para a construção de um programa
completo a partir dos pedaços:
• Header: descreve o conteúdo do código objeto;
• Text Segment: instruções traduzidas;
• Static Data Segment: dados alocados durante a vida do
programa (variáveis globais);
• Relocation Info: para conteúdos que dependem da
localização absoluta do programa carregado;
• Symbol Table: definições globais e referências externas;
• Debug Info: para associação com o código fonte.
Produzindo um Código Objeto
(Partes dos Programas)
André Aziz ([email protected])
83
21/11/2013
• Produz uma imagem executável:
1. Unifica os segmentos;
2. Resolve os rótulos (determina o seus endereços);
3. Corrige as referências externas e as dependente de
localização;
• Pode deixar as dependências de localização para serem
corrigidas durante o processo de Loader:
• Com memória virtual, isso não é necessário;
• Programa pode ser carregado em uma localização absoluta
no espaço da memória virtual.
“Linkando” Código Objeto
André Aziz ([email protected])
84
21/11/2013
• Carrega o arquivo de imagem do disco para a memória:
1. Lê o Header para determinar o tamanho dos segmentos;
2. Cria um espaço de endereçamento virtual;
3. Copia instruções e os dados inicializados para a memória:
•
Ou configura as entradas da tabela de páginas para que
ocorram faltas;
4. Carrega os argumentos na pilha;
5. Inicializa os registradores (incluindo $sp, $fp, $gp);
6. Desvia para a rotina de inicialização:
•
•
Copia os argumentos para $a0, ... e chama a “main”;
Quando a “main” retorna, executa a Syscall Exit.
Carregando um programa
André Aziz ([email protected])
85
21/11/2013
• Só carrega/linka a biblioteca de procedimentos quando é
chamada:
• Necessita que o código do procedimento seja realocável;
• Evita o “inchaço” do executável causado pela linkagem
estática de todas as bibliotecas referenciadas;
• Automaticamente pega novas versões das bibliotecas.
“Linkagem” Dinâmica
André Aziz ([email protected])
86
21/11/2013
Indirection table
Stub: Loads routine ID,
Jump to linker/loader
Linker/loader code
Dynamically
mapped code
Lazy Linkage
André Aziz ([email protected])
87
21/11/2013
Simple portable
instruction set for
the JVM
Compiles
bytecodes of
“hot” methods
into native code
for host
machine
Iniciando aplicações Java
André Aziz ([email protected])
Interprets
bytecodes
88
21/11/2013
COLOCANDO TUDO JUNTO
89
André Aziz ([email protected])
21/11/2013
• Ilustra o uso de instruções em Assembly para uma função
de Bubble Sort em C;
• Procedimento de SWAP (folha):
void swap(int v[], int k)
{
int temp;
temp = v[k];
v[k] = v[k+1];
v[k+1] = temp;
}
• v em $a0, k em $a1, temp em $t0
Exemplo: Ordenação em C
André Aziz ([email protected])
90
21/11/2013
swap: sll $t1, $a1, 2
# $t1 = k * 4
add $t1, $a0, $t1 # $t1 = v+(k*4)
#
(address of v[k])
lw $t0, 0($t1)
# $t0 (temp) = v[k]
lw $t2, 4($t1)
# $t2 = v[k+1]
sw $t2, 0($t1)
# v[k] = $t2 (v[k+1])
sw $t0, 4($t1)
# v[k+1] = $t0 (temp)
jr $ra
# return to calling routine
Procedimento de SWAP
André Aziz ([email protected])
91
21/11/2013
• Não-folha (chama swap):
void sort (int v[], int n)
{
int i, j;
for (i = 0; i < n; i += 1) {
for (j = i – 1;
j >= 0 && v[j] > v[j + 1];
j -= 1) {
swap(v,j);
}
}
}
• v em $a0, k em $a1, i em $s0, j em $s1
Procedimento de ordenação em C
André Aziz ([email protected])
92
21/11/2013
move $s2, $a0
# save $a0 into $s2
move $s3, $a1
# save $a1 into $s3
move $s0, $zero
# i = 0
for1tst: slt $t0, $s0, $s3
# $t0 = 0 if $s0 ≥ $s3 (i ≥ n)
beq $t0, $zero, exit1 # go to exit1 if $s0 ≥ $s3 (i ≥ n)
addi $s1, $s0, –1
# j = i – 1
for2tst: slti $t0, $s1, 0
# $t0 = 1 if $s1 < 0 (j < 0)
bne $t0, $zero, exit2 # go to exit2 if $s1 < 0 (j < 0)
sll $t1, $s1, 2
# $t1 = j * 4
add $t2, $s2, $t1
# $t2 = v + (j * 4)
lw
$t3, 0($t2)
# $t3 = v[j]
lw
$t4, 4($t2)
# $t4 = v[j + 1]
slt $t0, $t4, $t3
# $t0 = 0 if $t4 ≥ $t3
beq $t0, $zero, exit2 # go to exit2 if $t4 ≥ $t3
move $a0, $s2
# 1st param of swap is v (old $a0)
move $a1, $s1
# 2nd param of swap is j
jal swap
# call swap procedure
addi $s1, $s1, –1
# j –= 1
j
for2tst
# jump to test of inner loop
exit2:
addi $s0, $s0, 1
# i += 1
j
for1tst
# jump to test of outer loop
Corpo do procedimento
André Aziz ([email protected])
Move
params
Outer loop
Inner loop
Pass
params
& call
Inner loop
Outer loop
93
21/11/2013
sort:
addi $sp,$sp, –20
sw $ra, 16($sp)
sw $s3,12($sp)
sw $s2, 8($sp)
sw $s1, 4($sp)
sw $s0, 0($sp)
…
…
exit1: lw $s0, 0($sp)
lw $s1, 4($sp)
lw $s2, 8($sp)
lw $s3,12($sp)
lw $ra,16($sp)
addi $sp,$sp, 20
jr $ra
#
#
#
#
#
#
#
make room on stack for 5 registers
save $ra on stack
save $s3 on stack
save $s2 on stack
save $s1 on stack
save $s0 on stack
procedure body
#
#
#
#
#
#
#
restore $s0 from stack
restore $s1 from stack
restore $s2 from stack
restore $s3 from stack
restore $ra from stack
restore stack pointer
return to calling routine
Procedimento completo
André Aziz ([email protected])
94
21/11/2013
Compiled with gcc for Pentium 4 under Linux
Relative Performance
3
140000
Instruction count
120000
2.5
100000
2
80000
1.5
60000
1
40000
0.5
20000
0
0
none
O1
O2
Clock Cycles
180000
160000
140000
120000
100000
80000
60000
40000
20000
0
none
O3
O1
O2
O3
O2
O3
CPI
2
1.5
1
0.5
0
none
O1
O2
O3
none
Efeitos da otimização do
compilador
André Aziz ([email protected])
O1
95
21/11/2013
Bubblesort Relative Performance
3
2.5
2
1.5
1
0.5
0
C/none
C/O1
C/O2
C/O3
Java/int
Java/JIT
Java/int
Java/JIT
Quicksort Relative Performance
2.5
2
1.5
1
0.5
0
C/none
C/O1
C/O2
C/O3
Quicksort vs. Bubblesort Speedup
3000
2500
2000
1500
Efeitos da
linguagem e algoritmo
1000
500
0
C/none
André Aziz ([email protected])
C/O1
C/O2
C/O3
Java/int
Java/JIT
96
21/11/2013
• Número de instruções e CPI não são bons avaliadores de
de desempenho isolados;
• Otimizações do compilador são sensíveis ao algoritmo;
• Código compilado para Java/JIT é significantemente mais
rápido que o interpretado pela JVM:
• Comparável com o código C otimizado;
• Nada pode corrigir um algoritmo ruim!
Lições aprendidas
André Aziz ([email protected])
97
21/11/2013
• Indexar array envolve:
• Multiplicação do índice pelo tamanho do elemento;
• Adicionar ao endereço base do array;
• Ponteiros corresponde diretamente ao endereço da
memória:
• Evita a complexidade de indexação.
Arrays vs. Ponteiros
André Aziz ([email protected])
98
21/11/2013
clear1(int array[], int size) {
int i;
for (i = 0; i < size; i += 1)
array[i] = 0;
}
clear2(int *array, int size) {
int *p;
for (p = &array[0]; p < &array[size];
p = p + 1)
*p = 0;
}
move $t0,$zero
loop1: sll $t1,$t0,2
add $t2,$a0,$t1
move $t0,$a0
# p = & array[0]
sll $t1,$a1,2
# $t1 = size * 4
add $t2,$a0,$t1 # $t2 =
#
&array[size]
loop2: sw $zero,0($t0) # Memory[p] = 0
addi $t0,$t0,4 # p = p + 4
slt $t3,$t0,$t2 # $t3 =
#(p<&array[size])
bne $t3,$zero,loop2 # if (…)
# goto loop2
# i = 0
# $t1 = i * 4
# $t2 =
#
&array[i]
sw $zero, 0($t2) # array[i] = 0
addi $t0,$t0,1
# i = i + 1
slt $t3,$t0,$a1 # $t3 =
#
(i < size)
bne $t3,$zero,loop1 # if (…)
# goto loop1
Exemplo: Limpando um array
André Aziz ([email protected])
99
21/11/2013
• Multiplicar a “força reduzida” do uso do shift;
• Versão com array necessita que os shifts estejam dentro
do loop;
• Parte do cálculo do índice para o i incrementado;
• Compilador por alcançar o mesmo efeito com o uso
manual de ponteiros:
• Eliminação da variável de indução;
• Melhor para fazer o programa mais claro e seguro;
Comparação entre Array e
Ponteiro
André Aziz ([email protected])
100
21/11/2013
• ARM: processador embarcado mais popular;
• Conjunto de instruções similar ao do MIPS;
ARM
MIPS
1985
1985
Instruction size
32 bits
32 bits
Address space
32-bit flat
32-bit flat
Data alignment
Aligned
Aligned
9
3
15 × 32-bit
31 × 32-bit
Memory
mapped
Memory
mapped
Date announced
Data addressing modes
Registers
Input/output
Similaridades ARM & MIPS
André Aziz ([email protected])
101
21/11/2013
• Usa códigos condicionais para resultado de uma operação
lógica/aritmética;
• Negativo, zero, carry, overflow;
• Compara instruções para mudar os código de condição sem
manter o resultado;
• Cada instrução pode ser condicional:
• 4 bits mais significativos da instrução: valor da condição;
• Evita branchs sobre instruções simples.
Comparação e Desvio no
ARM
André Aziz ([email protected])
102
21/11/2013
Codificação das Instruções
André Aziz ([email protected])
103
21/11/2013
• Evolução com compatibilidade:
• 8080 (1974): 8-bit microprocessor
• Accumulator, plus 3 index-register pairs
• 8086 (1978): 16-bit extension to 8080
• Complex instruction set (CISC)
• 8087 (1980): floating-point coprocessor
• Adds FP instructions and register stack
• 80286 (1982): 24-bit addresses, MMU
• Segmented memory mapping and protection
• 80386 (1985): 32-bit extension (now IA-32)
• Additional addressing modes and operations
• Paged memory mapping as well as segments
Intel x86 ISA
André Aziz ([email protected])
104
21/11/2013
• ...
• i486 (1989): pipelined, on-chip caches and FPU
• Compatible competitors: AMD, Cyrix, …
• Pentium (1993): superscalar, 64-bit datapath
• Later versions added MMX (Multi-Media eXtension)
instructions
• The infamous FDIV bug
• Pentium Pro (1995), Pentium II (1997)
• New microarchitecture (see Colwell, The Pentium Chronicles)
• Pentium III (1999)
• Added SSE (Streaming SIMD Extensions) and associated
registers
• Pentium 4 (2001)
• New microarchitecture
• Added SSE2 instructions
Intel x86 ISA
André Aziz ([email protected])
105
21/11/2013
• ...
• AMD64 (2003): extended architecture to 64 bits
• EM64T – Extended Memory 64 Technology (2004)
• AMD64 adopted by Intel (with refinements)
• Added SSE3 instructions
• Intel Core (2006)
• Added SSE4 instructions, virtual machine support
• AMD64 (announced 2007): SSE5 instructions
• Intel declined to follow, instead…
• Advanced Vector Extension (announced 2008)
• Longer SSE registers, more instructions
• Se a Intel não estender a compatibilidade, seus
concorrentes irão!
• Technical elegance ≠ market success
Intel x86 ISA
André Aziz ([email protected])
106
21/11/2013
Registradores do x86
André Aziz ([email protected])
107
21/11/2013
• Dois operandos por instrução:
Source/dest operand
Second source operand
Register
Register
Register
Immediate
Register
Memory
Memory
Register
Memory
Immediate
• Modos de endereçamento da memória:
• Address in register
• Address = Rbase + displacement
• Address = Rbase + 2scale × Rindex (scale = 0, 1, 2, or 3)
• Address = Rbase + 2scale × Rindex + displacement
Modos de endereçamento x86
André Aziz ([email protected])
108
21/11/2013
• Tamanho da
codificação
variável:
• Sufixo especifica
o modo de
endereçamento;
• Prefixo modifica
a operação:
• Tamanho do
operado,
repetição,
travamento, ...
Codificação das instruções
do x86
André Aziz ([email protected])
109
21/11/2013
• Instruções complexas fazem a implementação difícil:
• Hardware traduz instruções para microoperações mais
simples:
• Instruções simples: 1 – 1;
• Instruções complexas: 1 – muitos;
• Microengine similar a um RISC;
• Marke share tornou isto economicamente viável;
• Desempenho comparável ao RISC:
• Compiladores evitam instruções complexas.
Implementando IA-32
André Aziz ([email protected])
110
21/11/2013
• Instruções poderosas  alto desempenho:
• Poucas instruções necessárias;
• Instruções complexas são difíceis de implementar:
• Podem deixar lenta todas as instruções, incluindo as simples;
• Compiladores são bons em fazer código rápido com
instruções simples;
• Uso de código Assembly para alto desempenho:
• Compiladores modernos conseguem lidar melhor com
processadores modernos;
• Mais linhas de código  mais erros e menos
produtividade
Falácias
André Aziz ([email protected])
111
21/11/2013
• Compatibilidade  conjunto de instruções não muda:
• Eles acrescentam mais instruções.
x86 instruction set
Falácias
André Aziz ([email protected])
112
21/11/2013
• Palavras sequenciais não são endereços sequenciais:
• Endereços são incrementados por 4 e não por 1!
• Mantendo um ponteiro para um variável local depois que
o processo retorna:
• Ex. passando o ponteiro de volta via um argumento;
• Ponteiros ficam inválidos após serem removidos da pilha.
Armadilhas
André Aziz ([email protected])
113
21/11/2013
• Princípios de projeto:
1.
2.
3.
4.
Simplicidade favorece regularidade;
Menor é mais rápido;
Faça o caso comum mais rápido;
Bons projetos demandam bons compromissos;
• Camadas de software/hardware:
• Compilador, Assembler, hardware;
• MIPS: típico ISA dos RISCs:
• Diferente do x86 – CISC.
Relembrando
André Aziz ([email protected])
114
21/11/2013
• Meça a execução das instruções do MIPS em programas
de benchmarks:
• Considere fazendo o caso comum mais rápido;
• Considere bons compromissos.
Instruction class
MIPS examples
SPEC2006 Int
SPEC2006 FP
Arithmetic
add, sub, addi
16%
48%
Data transfer
lw, sw, lb, lbu,
lh, lhu, sb, lui
35%
36%
Logical
and, or, nor, andi,
ori, sll, srl
12%
4%
Cond. Branch
beq, bne, slt,
slti, sltiu
34%
8%
Jump
j, jr, jal
2%
0%
Relembrando
André Aziz ([email protected])
115
21/11/2013
Arquitetura e Organização
de Computadores
Capítulo 2 – Conjunto de Instruções
Download