• Nenhum resultado encontrado

Arquitetura e Organização de Computadores. Capítulo 2 Conjunto de Instruções

N/A
N/A
Protected

Academic year: 2021

Share "Arquitetura e Organização de Computadores. Capítulo 2 Conjunto de Instruções"

Copied!
116
0
0

Texto

(1)

Arquitetura e Organização

de Computadores

(2)

• Material adaptado de:

Patterson e Henessy,

(3)

Conjunto de Instruções - ISA

• É 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.

(4)

MIPS Instruction Set

• 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:

(5)

Operações Aritméticas

• Todo computador deve ser capaz de executar operações aritméticas:

• Notação da MIPS Assembly Language:

instrui o computado a adicionar duas variáveis b e c e colocar o resultado da soma em a:

add a, b, c

(6)

Operações Aritméticas

• Essa notação é fixa, ou seja, sem variações.

• Se você quiser fazer ...

então é necessário...

a = b + c + d + e

add a, b, c # The sum of b and c is placed in a. add a, a, d # The sum of b, c, and d is now in a. add a, a, e # The sum of b, c, d, and e is now in a.

(7)

Princípio de Projeto 1

• “Simplicidade favorece a regularidade”;

• Todas as operações aritméticas possuim o mesmo formato;

• Regularidade faz implementação mais simples;

(8)

Exemplo: Operações

aritméticas

• Código C:

f = (g + h) - (i + j);

• Código compilado do MIPS:

add t0, g, h # temp t0 = g + h add t1, i, j # temp t1 = i + j sub f, t0, t1 # f = t0 - t1

(9)

Operandos em registradores

• 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).

(10)

Princípio de Projeto 2

• “Menor é mais rápido”;

• Um número grande de registradores pode aumentar o tempo do ciclo de clock, tornando o sistema lento.

(11)

Exemplo: Operandos em

registradores

• 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

(12)

Como computadores podem

representar e acessar grandes

estruturas de dados?

• 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.

(13)

Operandos na Memória

• 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:

(14)

Operandos na memória

• “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.

(15)

OBS: O que é a memória?

• Memória é um grande unidimensional array com o endereço atuando como índice deste array;

(16)

Carregar dados da memória

• 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;

(17)

Exemplo 1: Operandos na

memória

• 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

(18)

Exemplo 2: Operandos na

memória

• 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

(19)

Operandos Imediatos

• 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

(20)

Princípio de Projeto 3

• “Faça o caso comum mais rápido”

• Pequenas constantes são comuns ao programas;

(21)

A constante Zero

• O registrador 0 ($zero) é a constante 0:

• Não pode ser sobrescrito;

• Útil para operações comuns:

• Ex: mover dados entre registradores:

(22)

NÚMEROS INTEIROS COM

OU SEM SINAL

(23)

Números Inteiros Binários

sem Sinal

• Dado um número de n-bits:

• 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 0 0 1 1 2 n 2 n 1 n 1 n

2

x

2

x

2

x

2

x

x

(24)

Inteiros em Complemento a

2 com Sinal

• Dado um número de n-bits:

• 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 0 0 1 1 2 n 2 n 1 n 1 n

2

x

2

x

2

x

2

x

x

(25)

Inteiros em Complemento a

2 com Sinal

• 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

(26)

Negação com Sinal

• Complemento dos bits somados a 1:

• Complemento significa: 1 → 0, 0 → 1 • Exemplo: negar +2 • +2 = 0000 0000 … 00102 • –2 = 1111 1111 … 11012 + 1 = 1111 1111 … 11102

x

1

x

1

1

1

1

1

...1

1

1

x

x

2

(27)

Extensão de Sinal

• 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

(28)

REPRESENTANDO

INSTRUÇÕES

(29)

Representação de uma

instrução

• 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;

(30)

Instruções do formato R

• 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).

op rs rt rd shamt funct

(31)

Exemplo do formato R

• add $t0, $s1, $s2

op rs rt rd shamt funct

6 bits 5 bits 5 bits 5 bits 5 bits 6 bits

special $s1 $s2 $t0 0 add

0 17 18 8 0 32

000000 10001 10010 01000 00000 100000

(32)

Hexadecimal

• Base 16:

• Representação compacta de cadeias de bits;

• 4 bits por cada dígito hexadecimal;

• Example: eca8 6420

(33)

Instruções do formato I

• 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;

op rs rt constant or address

(34)

Princípio de Projeto 4

• “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.

(35)

Exemplo: Traduzindo Assembly para

código de máquina

• Se $t1 tem o endereço base do array A e $s2 corresponde ao, então a sentença:

é compilada para:

• Qual é o código de máquina para essas três instruções?

A[300] = h + A[300];

lw $t0,1200($t1) # Temporary reg $t0 gets A[300] add $t0,$s2,$t0 # Temporary reg $t0 gets h + A[300] sw $t0,1200($t1) # Stores h + A[300] back into A[300]

(36)

Computadores com

programas armazenados

• 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.

(37)
(38)

Operações Lógicas

• Instruções para manipulação da cadeia de bits:

• Útil para extração ou inserção de grupos de bits em uma palavra.

(39)

Operações de shift

• 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).

op rs rt rd shamt funct

(40)

Operações de AND

• Útil para mascarar bits em uma palavra:

• Selecionar alguns bits, limpando os outros com 0; and $t0, $t1, $t2 0000 0000 0000 0000 0000 1101 1100 0000 0000 0000 0000 0000 0011 1100 0000 0000 $t2 $t1 0000 0000 0000 0000 0000 1100 0000 0000 $t0

(41)

Operações de OR

• Útil para incluir bits em uma palavra:

• Seta alguns bits para 1 sem mudar os outros; or $t0,$t1, $t2 0000 0000 0000 0000 0000 1101 1100 0000 0000 0000 0000 0000 0011 1100 0000 0000 $t2 $t1 0000 0000 0000 0000 0011 1101 1100 0000 $t0

(42)

Operações de NOT

• Ú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

0000 0000 0000 0000 0011 1100 0000 0000 $t1

1111 1111 1111 1111 1100 0011 1111 1111 $t0

(43)

INSTRUÇÕES PARA TOMAR

DECISÕES

(44)

O diferencial do computador

• 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).

(45)

Operações condicionais

• 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

(46)

Exemplo: Compilando

sentenças if

• 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: …

(47)

Exemplo: Compilando

sentenças de Loop

• 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 $t1, $s3, 2 add $t1, $t1, $s6 lw $t0, 0($t1) bne $t0, $s5, Exit addi $s3, $s3, 1 j Loop Exit: …

(48)

Blocos básicos

• 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.

(49)

Mais operações condicionais

• 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 # if ($s1 < $s2) bne $t0, $zero, L # branch to L

(50)

Projeto das instruções de

desvio

• 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;

(51)

Sinal vs. Sem sinal

• 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

(52)

CHAMADA DE

(53)

Chamada de procedimento

• 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;

(54)

Convenção: Uso de

registradores

• $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);

(55)

Instruções para chamar

procedimentos

• 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

(56)

Exemplo: Chamada de

procedimento “folha”

• 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)

(57)

Exemplo: Chamada de

procedimento “folha”

• 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 Save $s0 on stack Procedure body Restore $s0 Result Return

(58)

Procedimentos não-”folha”

• 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;

(59)

Exemplo: Procedimento

não-”folha”

• Código C:

int fact (int n) {

if (n < 1) return f;

else return n * fact(n - 1); }

• Parâmetros em $a0

(60)

Código MIPS:

fact:

addi $sp, $sp, -8 # adjust stack for 2 items sw $ra, 4($sp) # save return address

sw $a0, 0($sp) # save argument slti $t0, $a0, 1 # test for n < 1 beq $t0, $zero, L1

addi $v0, $zero, 1 # if so, result is 1

addi $sp, $sp, 8 # pop 2 items from stack jr $ra # and return

L1: addi $a0, $a0, -1 # else decrement n jal fact # recursive call

lw $a0, 0($sp) # restore original n lw $ra, 4($sp) # and return address addi $sp, $sp, 8 # pop 2 items from stack mul $v0, $a0, $v0 # multiply to get result jr $ra # and return

(61)
(62)

Dados locais na pilha

• Variáveis locais armazenadas pelo procedimento;

• Janela do procedimento (frame):

• Usado por alguns compiladores para gerenciar o armazenamento na pilha

(63)

Layout da Memória

• 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;

(64)
(65)

Caracteres

• 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;

(66)

Operações com byte e

meia-palavra

• 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)

(67)

Exemplo: Copiar String

• 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;

(68)

Exemplo: Copiar String

MIPS code:

strcpy:

addi $sp, $sp, -4 # adjust stack for 1 item sw $s0, 0($sp) # save $s0

add $s0, $zero, $zero # i = 0

L1: add $t1, $s0, $a1 # addr of y[i] in $t1 lbu $t2, 0($t1) # $t2 = y[i]

add $t3, $s0, $a0 # addr of x[i] in $t3 sb $t2, 0($t3) # x[i] = y[i]

beq $t2, $zero, L2 # exit loop if y[i] == 0 addi $s0, $s0, 1 # i = i + 1

j L1 # next iteration of loop L2: lw $s0, 0($sp) # restore saved $s0

addi $sp, $sp, 4 # pop 1 item from stack jr $ra # and return

(69)

Constantes de 32-bits

• 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.

0000 0000 0111 1101 0000 0000 0000 0000

lhi $s0, 61

0000 0000 0111 1101 0000 1001 0000 0000

(70)

ENDEREÇAMENTO DE

DESVIOS

(71)

Endereçamento de desvios

condicionais (branch)

• As instruções de desvio especificam:

• Opcode, dois registradores, endereço alvo;

• Maioria dos desvios são desvios curtos:

• Para cima ou para baixo:

• Endereçamento relativo ao contador de programa (PC):

• Endereço Alvo = PC + (offset x 4);

• OBS: PC já incrementado de 4.

op rs rt constant or address

(72)

Endereçamento de desvios

incodicionais (jump)

• 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:

• (Pseudo) endereçamento direto:

• Endereço Alvo = PC31...28 : (address x 4)

Concatenação

op address

(73)

Exemplo: Endereçamento alvo

• 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 addi $s3, $s3, 1 80016 8 19 19 1 j Loop 80020 2 20000 Exit: … 80024

(74)

Desvios condicionais para

áreas distantes

• 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: beq $s0,$s1, L1 ↓ bne $s0,$s1, L2 j L1 L2: …

(75)

Resumo dos modos de

endereçamento

(76)
(77)

Sincronização

• 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;

(78)

Sincronização no MIPS

• 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:

(79)

Exemplo: Swap atômico

Swap atômico (test/set lock)

try: add $t0,$zero,$s4 ;copy exchange value ll $t1,0($s1) ;load linked

sc $t0,0($s1) ;store conditional beq $t0,$zero,try ;branch store fails

(80)
(81)

Tradução e Inicialização

Many compilers produce object modules directly

(82)

Pseudoinstruções

• 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

add $t0, $zero, $t1

blt $t0, $t1, L

slt $at, $t0, $t1 bne $at, $zero, L

(83)

Produzindo um Código Objeto

(Partes dos Programas)

• 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;

(84)

“Linkando” Código Objeto

• 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.

(85)

Carregando um programa

• 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”;

(86)

“Linkagem” Dinâmica

• 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;

(87)

Lazy Linkage

Indirection table

Stub: Loads routine ID, Jump to linker/loader

Linker/loader code

Dynamically mapped code

(88)

Iniciando aplicações Java

Simple portable instruction set for

the JVM Interprets bytecodes Compiles bytecodes of “hot” methods into native code

for host machine

(89)
(90)

Exemplo: Ordenação em C

• 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; }

(91)

Procedimento de SWAP

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)

(92)

Procedimento de ordenação em C

• 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

(93)

Corpo do procedimento

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

Pass params & call Move params Inner loop Outer loop Inner loop Outer loop

(94)

Procedimento completo

sort: addi $sp,$sp, –20 # make room on stack for 5 registers sw $ra, 16($sp) # save $ra on stack

sw $s3,12($sp) # save $s3 on stack sw $s2, 8($sp) # save $s2 on stack sw $s1, 4($sp) # save $s1 on stack sw $s0, 0($sp) # save $s0 on stack … # procedure body …

exit1: lw $s0, 0($sp) # restore $s0 from stack lw $s1, 4($sp) # restore $s1 from stack lw $s2, 8($sp) # restore $s2 from stack lw $s3,12($sp) # restore $s3 from stack lw $ra,16($sp) # restore $ra from stack addi $sp,$sp, 20 # restore stack pointer jr $ra # return to calling routine

(95)

Efeitos da otimização do

compilador

0 0.5 1 1.5 2 2.5 3 none O1 O2 O3 Relative Performance 0 20000 40000 60000 80000 100000 120000 140000 160000 180000 none O1 O2 O3 Clock Cycles 0 20000 40000 60000 80000 100000 120000 140000 none O1 O2 O3 Instruction count 0 0.5 1 1.5 2 none O1 O2 O3 CPI

(96)

Efeitos da

linguagem e algoritmo

0 500 1000 1500 2000 2500 3000

C/none C/O1 C/O2 C/O3 Java/int Java/JIT

Quicksort vs. Bubblesort Speedup 0 0.5 1 1.5 2 2.5

C/none C/O1 C/O2 C/O3 Java/int Java/JIT

Quicksort Relative Performance 0 0.5 1 1.5 2 2.5 3

C/none C/O1 C/O2 C/O3 Java/int Java/JIT

(97)

Lições aprendidas

• 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;

(98)

Arrays vs. Ponteiros

• 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:

(99)

Exemplo: Limpando um array

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 # i = 0 loop1: sll $t1,$t0,2 # $t1 = i * 4 add $t2,$a0,$t1 # $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

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 (…)

(100)

Comparação entre Array e

Ponteiro

• 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;

(101)

Similaridades ARM & MIPS

• ARM: processador embarcado mais popular;

• Conjunto de instruções similar ao do MIPS;

ARM MIPS

Date announced 1985 1985

Instruction size 32 bits 32 bits

Address space 32-bit flat 32-bit flat

Data alignment Aligned Aligned

Data addressing modes 9 3

Registers 15 × 32-bit 31 × 32-bit

Input/output Memory

mapped

Memory mapped

(102)

Comparação e Desvio no

ARM

• 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;

(103)
(104)

Intel x86 ISA

• 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

(105)

Intel x86 ISA

• ...

• 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

(106)

Intel x86 ISA

• ...

• 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!

(107)
(108)

Modos de endereçamento x86

• Dois operandos por instrução:

• 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

Source/dest operand Second source operand Register Register

Register Immediate Register Memory

Memory Register Memory Immediate

(109)

Codificação das instruções

do x86

• Tamanho da codificação variável: • Sufixo especifica o modo de endereçamento; • Prefixo modifica a operação: • Tamanho do operado, repetição, travamento, ...

(110)

Implementando IA-32

• 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:

(111)

Falácias

• 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

(112)

Falácias

• Compatibilidade  conjunto de instruções não muda:

• Eles acrescentam mais instruções.

(113)

Armadilhas

• 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;

(114)

Relembrando

• Princípios de projeto:

1. Simplicidade favorece regularidade;

2. Menor é mais rápido;

3. Faça o caso comum mais rápido;

4. Bons projetos demandam bons compromissos;

• Camadas de software/hardware:

• Compilador, Assembler, hardware;

• MIPS: típico ISA dos RISCs:

(115)

Relembrando

• 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%

(116)

Arquitetura e Organização

de Computadores

Referências

Documentos relacionados

O programa Erro Zero, Atraso Zero, como o próprio nome diz, tem tolerância ZERO para erros e atrasos, e foi desenvolvido para que a qualidade dos serviços prestados aumentasse

Na aba header temos acesso a informações de registro da ordem de compra como o centro de entrega, as condições de pago, o texto que é o campo com detalhes a serem inseridas pelo

Os impetrantes sustentam que a informação de que a família do magistrado trabalha com bijuterias é pública e foi noticiada pela imprensa. Acrescentam que a

Destarte, analisando o conceito de direito à intimidade, constata-se claramente que os dados genéticos, como informações diretamente relacionadas ao ser humano, são

Não apresentarei o argumento neste trabalho, pois importa dizer sobre a solução ter vindo, então, ao deixar de lado as recomendações de escrita de roteiro que eu seguira

Na análise do jurídico e literário, na seara da propriedade intelectual, utilizando como objeto de estudo as obras de Machado de Assis, pode-se perceber a presença de

Porém a exploração do trabalho muitas vezes se dá de maneira oculta, o que contribui para o trabalhador se tornar um sujeito alienado incapaz de perceber a sua condição no

Foi possível observar o crescimento do tipo alométrico positivo, com valor θ igual a 3,067, na população de Divaricella quadrisulcata, para a relação entre o Wb x Lt,