Linguagem de Máquina - Luciano José Senger
Linguagem de Máquina - Luciano José Senger
Linguagem de Máquina - Luciano José Senger
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
Introdução Introdu ão<br />
Organização Organiza ão e Arquitetura<br />
<strong>de</strong> computadores<br />
Instruções: a linguagem <strong>de</strong> máquina<br />
Prof. Dr. <strong>Luciano</strong> <strong>José</strong> <strong>Senger</strong><br />
• Para controlar o hardware do computador, é<br />
necessário falar a sua linguagem<br />
• Palavras da linguagem do computador são<br />
chamadas <strong>de</strong> instruções = vocabulário é chamado<br />
<strong>de</strong> conjunto <strong>de</strong> instruções<br />
• Apresentação das instruções através <strong>de</strong> uma<br />
abordagem top-down<br />
• Linguagens <strong>de</strong> computadores são semelhantes<br />
(entre diferentes arquiteturas), ao contrário da<br />
linguagem dos humanos<br />
Conteúdo Conte do<br />
• Introdução<br />
• Operações no hardware do computador<br />
• Operandos do hardware do computador<br />
• Representando instruções no computador<br />
• Operações lógicas<br />
• Instruções para tomada <strong>de</strong> <strong>de</strong>cisões<br />
• Suporte para procedimentos no hardware do computador<br />
• Comunicando-se com as pessoas<br />
• En<strong>de</strong>reçamento no MIPS para operados imediatos e en<strong>de</strong>reços <strong>de</strong> 32<br />
bits<br />
• Traduzindo e iniciando um programa<br />
• Como os compiladores otimizam<br />
• Um exemplo <strong>de</strong> or<strong>de</strong>nação na linguagem C para juntar tudo isso<br />
• Vida real: instruções do IA-32<br />
• Falácias e armadilhas<br />
• Comentários finais<br />
• Leituras e exercícios<br />
Introdução Introdu ão<br />
Introdução Introdu ão Introdução Introdu ão<br />
• Conjunto <strong>de</strong> instruções (a ponta do iceberg)<br />
• Exemplo: MIPS (http://en.wikipedia.org/wiki/MIPS_architecture)<br />
– Conjunto <strong>de</strong> instruções criados a partir da década <strong>de</strong> 80<br />
– 100 milhões <strong>de</strong> processadores fabricados em 2002<br />
– ATI, Broadcom, Cisco, NEC, Nintendo, Silicon<br />
Graphics, Sony, Texas Instruments e Toshiba<br />
• Processador RISC (conjunto reduzido <strong>de</strong><br />
instruções)<br />
– Tamanho <strong>de</strong> instruções fixo (fixed instruction lengths)<br />
– Instruções <strong>de</strong> load-store (load-store instruction sets)<br />
– Modos <strong>de</strong> en<strong>de</strong>reçamento limitado (limited addressing mo<strong>de</strong>s)<br />
– Operações limitadas (limited operations)<br />
• É fácil ver, por métodos lógicos formais, que existem<br />
certos [conjuntos <strong>de</strong> instruções] que são a<strong>de</strong>quados<br />
para controlar e causar a execução <strong>de</strong> qualquer<br />
seqüência <strong>de</strong> operações... As consi<strong>de</strong>rações <strong>de</strong>cisivas,<br />
do ponto <strong>de</strong> vista atual, na seleção <strong>de</strong> um [conjunto <strong>de</strong><br />
instruções], são mais <strong>de</strong> natureza prática: a<br />
simplicida<strong>de</strong> do equipamento exigido pelo [conjunto <strong>de</strong><br />
instruções] e a clareza <strong>de</strong> sua aplicação para os<br />
problemas realmente importantes, junto com a<br />
velocida<strong>de</strong> com que tratam esses problemas<br />
– Burks, Goldstine e von Neumann, 1947<br />
• Arquiteturas <strong>de</strong> programa<br />
armazenado<br />
• Control necessita<br />
1. Instruções <strong>de</strong> entrada da<br />
memória<br />
2. Sinais para controlar o fluxo <strong>de</strong><br />
informação entre os<br />
componentes do caminho <strong>de</strong><br />
dados<br />
3. Sequenciamento <strong>de</strong> instruções<br />
CPU<br />
Control<br />
Datapath<br />
Exec<br />
Memory Devices<br />
Fetch<br />
Deco<strong>de</strong><br />
Input<br />
Output<br />
• Datapath tem<br />
– componentes – unida<strong>de</strong>s funcionais e banco <strong>de</strong> registradores<br />
– Interconexões - componentes que são conectados <strong>de</strong> forma que as<br />
instruções possam ser executadas e os dados possam ser trazidos e<br />
armazenados na memória
Conteúdo Conte do<br />
• Introdução <br />
• Operações no hardware do computador<br />
• Operandos do hardware do computador<br />
• Representando instruções no computador<br />
• Operações lógicas<br />
• Instruções para tomada <strong>de</strong> <strong>de</strong>cisões<br />
• Suporte para procedimentos no hardware do computador<br />
• Comunicando-se com as pessoas<br />
• En<strong>de</strong>reçamento no MIPS para operados imediatos e en<strong>de</strong>reços <strong>de</strong> 32<br />
bits<br />
• Traduzindo e iniciando um programa<br />
• Como os compiladores otimizam<br />
• Um exemplo <strong>de</strong> or<strong>de</strong>nação na linguagem C para juntar tudo isso<br />
• Vida real: instruções do IA-32<br />
• Falácias e armadilhas<br />
• Comentários finais<br />
• Leituras e exercícios<br />
Operações Opera ões do hardware do computador<br />
• O número natural <strong>de</strong> operandos para uma<br />
operação <strong>de</strong> adição é três<br />
• Exigir que cada instrução tenha exatamente três<br />
operações nem mais nem menos, está <strong>de</strong> acordo<br />
com manter o hardware simples: o hardware para<br />
um número variável <strong>de</strong> operandos é mais<br />
complicado do que o hardware para um número<br />
fixo:<br />
• Princípio <strong>de</strong> projeto 1: simplicida<strong>de</strong> favorece a<br />
regularida<strong>de</strong><br />
Operações Opera ões no hardware do computador<br />
• Compilando uma instrução complexa no MIPS<br />
f = (g + h) – (i + j)<br />
• O compilador precisa <strong>de</strong>smembrar essa instrução em<br />
várias instruções assembly, pois somente uma operação é<br />
realizada por instrução MIPS<br />
add t0, g, h # var. temp. t0 contém g+h<br />
add t1, i, j # var. temp. t1 contém i+j<br />
sub f, t0, t1 # f recebe t0 – t1<br />
• Note que uma expressão na linguagem C gera 3 instruções<br />
assembly para o MIPS<br />
• Reflexão: um número maior <strong>de</strong> instruções <strong>de</strong> máquina por<br />
expressão é melhor ou pior?<br />
Operações Opera ões do hardware do computador<br />
• Todo computador precisa realizar operações<br />
aritméticas<br />
add a, b, c<br />
• Instrui o computador para realizar a soma entre as<br />
variáveis b e c e armazenar o resultado em a<br />
• Exemplo: colocar a soma <strong>de</strong> b, c, d, e e na variável<br />
a:<br />
• Em linguagem <strong>de</strong> alto nível a = b + c + d + e<br />
• Em Assembly MIPS:<br />
add a, b, c # soma b+c é colocada em a<br />
add a, a, d # soma b+c+d está em a<br />
add a, a, e # soma b+c+d+e está em a<br />
Operações Opera ões do hardware do computador<br />
• Contra-exemplo: IA-32 (p.e. Pentium)<br />
– ADD AX,BX<br />
• Compilando duas instruções <strong>de</strong> atribuição C no<br />
MIPS:<br />
a = b + c;<br />
d = a – e;<br />
– a tradução é realizada pelo compilador<br />
– Em MIPS:<br />
add a, b, c<br />
sub d, a, e<br />
Conteúdo Conte do<br />
• Introdução <br />
• Operações no hardware do computador <br />
• Operandos do hardware do computador<br />
• Representando instruções no computador<br />
• Operações lógicas<br />
• Instruções para tomada <strong>de</strong> <strong>de</strong>cisões<br />
• Suporte para procedimentos no hardware do computador<br />
• Comunicando-se com as pessoas<br />
• En<strong>de</strong>reçamento no MIPS para operados imediatos e en<strong>de</strong>reços <strong>de</strong> 32<br />
bits<br />
• Traduzindo e iniciando um programa<br />
• Como os compiladores otimizam<br />
• Um exemplo <strong>de</strong> or<strong>de</strong>nação na linguagem C para juntar tudo isso<br />
• Vida real: instruções do IA-32<br />
• Falácias e armadilhas<br />
• Comentários finais<br />
• Leituras e exercícios
Operandos no hardware do computador<br />
• Ao contrário dos programas nas linguagens <strong>de</strong><br />
alto nível, os operandos das instruções aritméticas<br />
são restritos, precisam ser <strong>de</strong> um grupo limitado<br />
<strong>de</strong> locais especiais, embutidos diretamente no<br />
hardware, chamados registradores (registers)<br />
• Os registradores são os tijolos da construção do<br />
computador – primitivas usadas no projeto do<br />
computador e são visíveis para o programador<br />
• O tamanho dos registrados na arquitetura MIPS é<br />
32 bits; grupos <strong>de</strong> 32 bits ocorrem com tanta<br />
freqüência no MIPS que recebem o nome <strong>de</strong><br />
palavra (word)<br />
Operandos no hardware do computador<br />
• Uma diferença entre variáveis <strong>de</strong> um programa em<br />
linguagem <strong>de</strong> alto nível e os registradores é que o número<br />
<strong>de</strong> registradores é limitado<br />
• O computador MIPS tem 32 registradores<br />
• Princípio <strong>de</strong> projeto 2: menor significa mais rápido<br />
– Uma quantida<strong>de</strong> muito gran<strong>de</strong> <strong>de</strong> registradores po<strong>de</strong> aumentar o tempo do<br />
ciclo <strong>de</strong> clock simplesmente porque os sinais eletrônicos levam mais tempo<br />
quando precisam atravessar uma distância maior<br />
• Deve-se equilibrar o “<strong>de</strong>sejo” dos programas por mais<br />
registradores com o <strong>de</strong>sejo do projetista <strong>de</strong> manter o ciclo<br />
<strong>de</strong> clock mais rápido<br />
• Um número maior <strong>de</strong> registradores necessita <strong>de</strong> um<br />
número maior <strong>de</strong> bits para representação: influência no<br />
tamanho da instrução<br />
Operandos no hardware do computador<br />
• Operandos na memória<br />
– Operações aritméticas só ocorrem com os registradores<br />
nas instruções MIPS; assim o MIPS <strong>de</strong>ve ter instruções<br />
que transferem os dados entre o processador e a<br />
memória: instruções <strong>de</strong> transferência <strong>de</strong> dados<br />
– Para acessar uma word na memória, é necessário passar<br />
o en<strong>de</strong>reço <strong>de</strong> memória a ser utilizado<br />
Operandos no hardware do computador<br />
$at<br />
$gp<br />
$sp<br />
$fp<br />
$ra<br />
Name<br />
$zero<br />
$v0 - $v1<br />
$a0 - $a3<br />
$t0 - $t7<br />
$s0 - $s7<br />
$t8 - $t9<br />
Register<br />
Number<br />
0<br />
1<br />
2-3<br />
4-7<br />
8-15<br />
16-23<br />
24-25<br />
28<br />
29<br />
30<br />
31<br />
reserved for assembler<br />
arguments<br />
Usage<br />
constant 0 (hardware)<br />
returned values<br />
temporaries<br />
saved values<br />
temporaries<br />
global pointer<br />
stack pointer<br />
frame pointer<br />
return addr (hardware)<br />
Preserve<br />
on call?<br />
Operandos no hardware do computador<br />
n.a.<br />
n.a.<br />
no<br />
yes<br />
no<br />
yes<br />
no<br />
yes<br />
yes<br />
yes<br />
yes<br />
• A convenção no MIPS é usar nomes com um sinal<br />
<strong>de</strong> $ seguido <strong>de</strong> dois caracteres para representar<br />
um registrador.<br />
– $S0, $S1, $T0, $T1<br />
• Compilando uma atribuição em C usando<br />
registradores:<br />
f = (g + h) – (i + j)<br />
add $t0, $s1, $s2<br />
add $t1, $s3, $s4<br />
sub $s0, $t0, $t1<br />
Operandos no hardware do computador<br />
• A instrução que copia dados da memória para um<br />
registrador tradicionalmente é chamada <strong>de</strong> load<br />
• O formato da instrução load é o nome da operação<br />
seguido pelo registrador a ser carregado, <strong>de</strong>pois<br />
uma constante e o registrador usado para acessar<br />
a memória.<br />
• A soma da parte constante da instrução com o<br />
conteúdo do segundo registrador forma o<br />
en<strong>de</strong>reço <strong>de</strong> memória
Operandos no hardware do computador<br />
• Compilando uma atribuição quando um operando<br />
está na memória<br />
– Vamos supor que A seja uma sequência <strong>de</strong> 100 words e<br />
que o compilador tenha associado as variáveis g e h aos<br />
registradores $s1 e $s2. Vamos supor que o en<strong>de</strong>reço<br />
inicial da seqüência esteja no en<strong>de</strong>reço armazenado em<br />
$s3 (en<strong>de</strong>reço base)<br />
g = h + A[8];<br />
– embora haja uma única operação nessa instrução <strong>de</strong><br />
atribuição, um dos operandos está na memória, <strong>de</strong><br />
modo que precisamos transferir A[8] para um<br />
registrador ($s3 contém elemento base) :<br />
lw $t0, 8($s3)<br />
#registrador temporário recebe A[8]<br />
Operandos no hardware do computador<br />
• Interface hardware/software<br />
– Além <strong>de</strong> associar variáveis a registradores, o compilador aloca<br />
estrutura <strong>de</strong> dados, como vetores, em locais na memória<br />
– Como os bytes <strong>de</strong> 8 bits são úteis em muitos programas, a maioria<br />
das arquiteturas en<strong>de</strong>reça bytes individuais<br />
– En<strong>de</strong>reços <strong>de</strong> words combinam os en<strong>de</strong>reços dos 4 bytes <strong>de</strong>ntro da<br />
palavra<br />
• No MIPS, palavras precisam começar em en<strong>de</strong>reços que<br />
sejam múltiplos <strong>de</strong> 4<br />
Operandos no hardware do computador<br />
• Compilando com load e store<br />
– Suponha que a variável h esteja associada ao registrador $s2 e o<br />
en<strong>de</strong>reço base do vetor A esteja armazenado em $s3. Qual código<br />
assembly do MIPS para a instrução <strong>de</strong> atribuição C a seguir?<br />
– A[12] = h + A[8]<br />
– Embora seja uma instrução na linguagem C, dois operandos estão<br />
na memória; são necessárias instruções para buscar os dois<br />
operandos da memória:<br />
lw $t0, 32($s3) # reg. temp. $t0 recebe A[8]<br />
add $t0, $s2, $t0 # reg. temp. $t0 recebe h + A[8]<br />
sw $t0, 48($s3) # armazena resultado em A[12]<br />
Operandos no hardware <strong>de</strong> computador<br />
• Compilando uma atribuição quando um<br />
operando está na memória (cont.)<br />
– A instrução seguinte (add) po<strong>de</strong> operar sobre o valor<br />
em $t0, já que é um registrador:<br />
lw $t0, 8($s3)<br />
add $s1, $s2, $t0<br />
– A constante na instrução é chamada <strong>de</strong> offset e o<br />
registrador acrescentado para formar o en<strong>de</strong>reço é<br />
chamado <strong>de</strong> registrador base<br />
Operandos no hardware do computador<br />
• No MIPS, palavras precisam começar em<br />
en<strong>de</strong>reços que sejam múltiplos <strong>de</strong> 4 (restrição <strong>de</strong><br />
alinhamento)<br />
• O en<strong>de</strong>reçamento em bytes afeta o índice do array:<br />
para obter o en<strong>de</strong>reço em bytes <strong>de</strong> maneira<br />
apropriada o offset necessita ser igual a 4x8=32<br />
• A instrução complementar ao load chama-se store;<br />
ela copia dados <strong>de</strong> um registrador para a memória<br />
• A instrução store é representada pelo mnemônico<br />
sw<br />
Operandos no hardware do computador<br />
• Interface hardware/software<br />
– Muitos programas têm mais variáveis do que os computadores têm<br />
registradores<br />
– O compilador tenta manter as variáveis mais utilizadas nos<br />
registradores e coloca as restantes na memória, usando load e store<br />
para movimentar os dados<br />
– O processo <strong>de</strong> colocar variáveis menos utilizadas na memória ou<br />
aquelas que só serão empregadas mais tar<strong>de</strong> é <strong>de</strong>nominado spilling<br />
registers<br />
– Registradores, apesar <strong>de</strong> serem mais reduzidos e terem um<br />
tamanho menor que a memória principal, são mais rápidos: isso<br />
<strong>de</strong>fine a preocupação com a utilização correta dos registradores<br />
• Constantes ou operandos imediatos<br />
– Muitas vezes, os valores que necessitam ser trabalhados são<br />
passados na instrução como constantes, e não como en<strong>de</strong>reços <strong>de</strong><br />
memória; quando os dados são passados <strong>de</strong>ssa forma, como<br />
constantes, é utilizado o modo <strong>de</strong> en<strong>de</strong>reçamento imediato
Operandos no hardware do computador<br />
• Trabalhando com constantes<br />
– Usando apenas instruções, teríamos <strong>de</strong> ler uma<br />
constante da memória para utilizá-la:<br />
lw $t0, EndConstante4($s1)<br />
add $s3, $s3, $t0<br />
– Supondo que EndConstante4 seja o en<strong>de</strong>reço <strong>de</strong><br />
memória para a constante 4<br />
– Uma alternativa que evita a instrução load, e assim uma<br />
leitura em memória, é oferecer instruções aritméticas<br />
em que o operando seja uma constante<br />
– Essa instrução (no caso <strong>de</strong> uma soma) é chamada <strong>de</strong><br />
add imediato, ou addi:<br />
addi $s3, $s3, 4 # $s3 = $s3 + 4<br />
Conteúdo Conte do<br />
• Introdução <br />
• Operações no hardware do computador <br />
• Operandos do hardware do computador <br />
• Representando instruções no computador<br />
• Operações lógicas<br />
• Instruções para tomada <strong>de</strong> <strong>de</strong>cisões<br />
• Suporte para procedimentos no hardware do computador<br />
• Comunicando-se com as pessoas<br />
• En<strong>de</strong>reçamento no MIPS para operados imediatos e en<strong>de</strong>reços <strong>de</strong> 32<br />
bits<br />
• Traduzindo e iniciando um programa<br />
• Como os compiladores otimizam<br />
• Um exemplo <strong>de</strong> or<strong>de</strong>nação na linguagem C para juntar tudo isso<br />
• Vida real: instruções do IA-32<br />
• Falácias e armadilhas<br />
• Comentários finais<br />
• Leituras e exercícios<br />
Representando instruções instru ões no computador<br />
• Traduzindo uma instrução assembly MIPS para<br />
uma instrução <strong>de</strong> máquina:<br />
add $t0, $s1, $s2<br />
0<br />
17<br />
18<br />
• Cada um <strong>de</strong>sse segmentos <strong>de</strong> uma instrução é chamado campo; o<br />
primeiro e o último campos combinados dizem ao computador MIPS<br />
que essa instrução realiza soma<br />
• O segundo campo indica o número do registrador que é o primeiro<br />
operando <strong>de</strong> origem da operação <strong>de</strong> soma (17 = $t1)<br />
• O terceiro campo indica o outro operando <strong>de</strong> origem (18 = $t2)<br />
• O quarto campo contém o número do registrador que receberá o<br />
resultado (8 = $s0)<br />
• O quinto campo não é empregado nessa instrução<br />
8<br />
0<br />
32<br />
Operandos no hardware do computador<br />
• Trabalhando com constantes (cont.)<br />
– Princípio <strong>de</strong> projeto 3: agilize os casos mais comuns<br />
– Os operandos com constantes ocorrem com bastante<br />
freqüência e, incluindo constantes <strong>de</strong>ntro das instruções<br />
aritméticas, as operações tornam-se mais rápidas para<br />
serem executadas<br />
Representando instruções instru ões no computador<br />
• Embora quando programa-se em assembly utilizase<br />
mnemônicos (como lw, sw, add e sub), as<br />
instruções são representadas e executadas através<br />
<strong>de</strong> um conjunto <strong>de</strong> bits<br />
• Além disso, como os registradores são parte <strong>de</strong><br />
quase todas as instruções, é preciso haver uma<br />
convenção para mapear os nomes dos<br />
registradores em números binários<br />
– $s0 a $s7 são mapeados nos registradores <strong>de</strong> 16 a 23;<br />
– $t0 a $t7 são mapeados nos registradores <strong>de</strong> 8 a 15;<br />
• Exercício: qual é o código binário para o<br />
registrador $s7?<br />
Representando instruções instru ões no computador<br />
• Esse layout da instrução é chamado <strong>de</strong> formato <strong>de</strong><br />
instrução<br />
• As instruções no MIPS tem todas 32 bits <strong>de</strong> tamanho<br />
• Os campos do MIPS<br />
op<br />
(6 bits)<br />
rs<br />
(5 bits)<br />
rt<br />
(5 bits)<br />
rd<br />
(5 bits)<br />
shamt<br />
(5 bits)<br />
Funct<br />
(6 bits)<br />
– op: operação básica, tradicionalmente chamada <strong>de</strong> opco<strong>de</strong><br />
– rs: o registrador do primeiro operando <strong>de</strong> origem<br />
– rt: o registrador do segundo operando <strong>de</strong> origem<br />
– rd: o registrador do operando <strong>de</strong> <strong>de</strong>stino<br />
– shamt: shift amount; quantida<strong>de</strong> <strong>de</strong> <strong>de</strong>slocamento<br />
– funct: função; esse campo seleciona a variante específica da<br />
operação no campo op, e as vezes, é chamado <strong>de</strong> código <strong>de</strong> função
Representando instruções instru ões no computador<br />
• Problemas <strong>de</strong> en<strong>de</strong>reçamento<br />
– Existe um problema quando uma instrução precisa <strong>de</strong> campos<br />
maiores do que aqueles mostrados. Por exemplo, a instrução lw<br />
precisa especificar dois registradores e uma constante; se o<br />
en<strong>de</strong>reço tivesse apenas 5 bits do formato anterior, a constante<br />
estaria limitada a 32 (2^5)<br />
– Existe então um conflito entre manter entre o <strong>de</strong>sejo <strong>de</strong> manter<br />
todas as instruções com o mesmo tamanho e o <strong>de</strong>sejo <strong>de</strong> ter uma<br />
instrução único<br />
– Princípio <strong>de</strong> Projeto 4: um bom projeto exige bons compromissos<br />
– O compromisso escolhido pelos projetistas do MIPS é manter todas<br />
as instruções com o mesmo tamanho, exigindo assim diferentes<br />
formatos para os campos para diferentes tipos <strong>de</strong> instruções<br />
– O formato anterior é chamado <strong>de</strong> tipo R (<strong>de</strong> registrador) ou<br />
formato R.<br />
– Um segundo tipo <strong>de</strong> formato <strong>de</strong> instrução é chamado <strong>de</strong> formato I,<br />
utilizando pelas instruções imediatas e <strong>de</strong> transferência <strong>de</strong> dados.<br />
Representando instruções instru ões no computador<br />
• Traduzindo do assembly MIPS para a linguagem <strong>de</strong> máquina<br />
– Se $t1 possui a base do array A e $s2 correspon<strong>de</strong> a h:<br />
– A[300] = h + A[300];<br />
– É compilada para:<br />
lw $t0, 1200($t1) # reg. $t0 recebe A[300]<br />
add $t0, $s2, $t0 # reg. $t0 recebe h + A[300]<br />
sw $t0, 1200($t1) # armazena h +A[300] na mem.<br />
35<br />
0<br />
43<br />
9<br />
18<br />
9<br />
8<br />
8<br />
8<br />
1200<br />
1200<br />
Representando instruções instru ões no computador<br />
• Por que o MIPS não tem uma instrução <strong>de</strong><br />
subtração imediata?<br />
– Constantes negativas aparecem com muito menos<br />
frequência em C e Java, e por isso não são o caso<br />
comum e não merecem suporte especial<br />
– Como o campo imediato mantém constantes negativas<br />
e positivas, a soma imediata <strong>de</strong> um valor negativo é<br />
igual a subtração imediata com um número positivo, <strong>de</strong><br />
modo que a subtração imediata é supérflua<br />
8<br />
0<br />
32<br />
Representando instruções instru ões no computador<br />
• Formato I<br />
op<br />
(6 bits)<br />
rs<br />
(5 bits)<br />
rt<br />
(5 bits)<br />
Constante ou en<strong>de</strong>reço<br />
(16 bits)<br />
– O en<strong>de</strong>reço <strong>de</strong> 16 bits significa que uma instrução lw po<strong>de</strong> carregar<br />
qualquer word <strong>de</strong>ntro <strong>de</strong> uma região <strong>de</strong> +/- 2^15 do en<strong>de</strong>reço do<br />
registrador base (8192 words)<br />
– De modo semelhante, a soma imediata é limitada a constantes que<br />
não sejam maiores do que 2^15<br />
lw $t0, 32($s3)<br />
– Aqui, 19 (para $s3) é colocado no campo rs, 8 (para $t0) é colocado<br />
no campo rt e 32 é colocado no campo <strong>de</strong> en<strong>de</strong>reço (veja que o<br />
formato mudou: o campo rt especifica o registrador <strong>de</strong> <strong>de</strong>stino, que<br />
recebe o resultado do lw<br />
Representando instruções instru ões no computador<br />
– A instrução lw é representada por 35 no opco<strong>de</strong><br />
– O registrador base 9 ($t1) é especificado no segundo campo (rs) e o<br />
registrador <strong>de</strong> <strong>de</strong>stino 8 ($t0) é especificado no terceiro campo (rt)<br />
– O offset para selecionar A[300] (1200=300x4) aparece no campo final<br />
– A instrução add é especificada com opco<strong>de</strong> 0 e funct 32<br />
– A instrução sw é i<strong>de</strong>ntificada com 43 no opco<strong>de</strong><br />
– Importante: lembre-se que os valores estão representados em<br />
35<br />
0<br />
43<br />
<strong>de</strong>cimal, mas na verda<strong>de</strong> são representados em binário.<br />
Conteúdo Conte do<br />
9<br />
18<br />
9<br />
8<br />
8<br />
8<br />
8<br />
1200<br />
0<br />
1200<br />
• Introdução <br />
• Operações no hardware do computador <br />
• Operandos do hardware do computador <br />
• Representando instruções no computador <br />
• Operações lógicas<br />
• Instruções para tomada <strong>de</strong> <strong>de</strong>cisões<br />
• Suporte para procedimentos no hardware do computador<br />
• Comunicando-se com as pessoas<br />
• En<strong>de</strong>reçamento no MIPS para operados imediatos e en<strong>de</strong>reços <strong>de</strong> 32<br />
bits<br />
• Traduzindo e iniciando um programa<br />
• Como os compiladores otimizam<br />
• Um exemplo <strong>de</strong> or<strong>de</strong>nação na linguagem C para juntar tudo isso<br />
• Vida real: instruções do IA-32<br />
• Falácias e armadilhas<br />
• Comentários finais<br />
• Leituras e exercícios<br />
32
Operações Opera ões lógicas l gicas<br />
• Embora o projeto do primeiros computadores se<br />
concentrasse em words completas, logo ficou claro que é<br />
útil atuar sobre campos <strong>de</strong> bits <strong>de</strong> uma word<br />
– Operações lógicas servem para empacotar e <strong>de</strong>sempacotar grupos<br />
<strong>de</strong> bits em words<br />
Operações lógicas<br />
Shift a esquerda<br />
Shift a direita<br />
AND bit a bit<br />
OR bit a bit<br />
NOT bit a bit<br />
Operadores C<br />
><br />
&<br />
Operações Opera ões lógicas l gicas<br />
• Operações <strong>de</strong> <strong>de</strong>slocamento<br />
|<br />
~<br />
Operadores Java<br />
><br />
&<br />
|<br />
~<br />
Instruções MIPS<br />
sll<br />
srl<br />
and, andi<br />
or, ori<br />
nor<br />
– O <strong>de</strong>slocamento lógico à esquerda <strong>de</strong> i bits gera o mesmo<br />
resultado que multiplicar por 2^i<br />
• Operações lógicas<br />
– A operação AND é útil para isolar bits <strong>de</strong> uma palavra (operações<br />
com máscara)<br />
and $t0, $t1, $t2 # $t0 = $t1 & $t2<br />
– Para colocar um bit em 1 em um grupo <strong>de</strong> bits, po<strong>de</strong>-se utilizar a<br />
operação OR<br />
Conteúdo Conte do<br />
or $t0, $t1, $t2 # $t0 = $t1 | $t2<br />
• Introdução <br />
• Operações no hardware do computador <br />
• Operandos do hardware do computador <br />
• Representando instruções no computador <br />
• Operações lógicas <br />
• Instruções para tomada <strong>de</strong> <strong>de</strong>cisões<br />
• Suporte para procedimentos no hardware do computador<br />
• Comunicando-se com as pessoas<br />
• En<strong>de</strong>reçamento no MIPS para operados imediatos e en<strong>de</strong>reços <strong>de</strong> 32<br />
bits<br />
• Traduzindo e iniciando um programa<br />
• Como os compiladores otimizam<br />
• Um exemplo <strong>de</strong> or<strong>de</strong>nação na linguagem C para juntar tudo isso<br />
• Vida real: instruções do IA-32<br />
• Falácias e armadilhas<br />
• Comentários finais<br />
• Leituras e exercícios<br />
Operações Opera ões lógicas l gicas<br />
• Operações <strong>de</strong> <strong>de</strong>slocamento (shifts)<br />
– Movem todos os bits <strong>de</strong> uma word para esquerda ou<br />
para direita, preenchendo com zero os bits que ficaram<br />
vazios<br />
– Shift left logical:<br />
sll $t2, $s0, 4 # reg $t2 = reg $s0
Instruções Instru ões para tomada <strong>de</strong> <strong>de</strong>cisões<br />
• Instruções <strong>de</strong> <strong>de</strong>svio condicional no MIPS<br />
– Branch if not equal (<strong>de</strong>svie se não for igual)<br />
Bne registrador1, registrador2, L1<br />
– Significa <strong>de</strong>sviar o fluxo <strong>de</strong> execução para o rótulo L1<br />
caso os valores contidos nos registradores registrador1 e<br />
registrador2 forem diferentes<br />
• Compilando if-then-else em <strong>de</strong>svios condicionais<br />
– No segmento <strong>de</strong> código a seguir f, g, h, i e j são<br />
variáveis. Se as cinco variáveis correspon<strong>de</strong>m aos cinco<br />
registradores <strong>de</strong> $s0 a $s4, qual é o código compilado<br />
para esta instrução if em C?<br />
if (i == j) f = g + h; else f = g – h;<br />
Instruções Instru ões para tomada <strong>de</strong> <strong>de</strong>cisões<br />
• Interface hardware/software<br />
– Compiladores criam estruturas mais próximas a<br />
linguagem humana como while, do until, etc.<br />
– Compilando um loop while em C<br />
While (save[i] == k)<br />
i+= 1;<br />
– Suponha que i e k correspondam aos registradores $s3 e<br />
$s5 e base do vetor save esteja em $s6. Qual o código<br />
em MIPS que correspon<strong>de</strong> a esse segmento C?<br />
Instruções Instru ões para tomada <strong>de</strong> <strong>de</strong>cisões<br />
• Bloco básico<br />
– Uma seqüência <strong>de</strong> instruções sem <strong>de</strong>svios (exceto, possivelmente<br />
no final) e sem <strong>de</strong>stinos <strong>de</strong> <strong>de</strong>svio ou rótulos <strong>de</strong> <strong>de</strong>svio (exceto,<br />
possivelmente, no início<br />
– Uma das primeiras fases da compilação é <strong>de</strong>smembrar o programa<br />
em blocos básicos<br />
• Testes <strong>de</strong> igualda<strong>de</strong> em assembly MIPS<br />
– Comparações são realizadas <strong>de</strong> forma que a instrução compara<br />
dois registradores e atribui 1 a um terceiro registrador se o<br />
primeiro for menor que o segundo; caso contrário, é atribuído 0<br />
– Set on less than (atribuir se menor que)<br />
slt $t0, $s3, $s4<br />
– Significa que é atribuído 1 ao registrador $t0 se o valor no<br />
registrador $s3 for menor que o valor no registrador $s4<br />
Instruções Instru ões para tomada <strong>de</strong> <strong>de</strong>cisões<br />
bne $s3, $s4, Else<br />
add $s0, $s1, $s2<br />
j Exit<br />
Else: sub $s0, $s1, $s2<br />
Exit:<br />
A instrução j implementa o <strong>de</strong>svio incondicional<br />
(jump)<br />
Instruções Instru ões para tomada <strong>de</strong> <strong>de</strong>cisões<br />
While (save[i] == k)<br />
i+= 1;<br />
Suponha que i e k correspondam aos registradores $s3 e<br />
$s5 e base do vetor save esteja em $s6. Qual o código em<br />
MIPS que correspon<strong>de</strong> a esse segmento C?<br />
loop: sll $t1, $s3, 2 # $t1 = 4 * i<br />
add $t1, $t1, $s6 # $t1 = en<strong>de</strong>reço <strong>de</strong> save[i]<br />
lw $t0, 0($t1) #$t0 = save[i]<br />
bne $t0, $s5, Exit # vá para Exit se save[i] k<br />
addi $s3, $s3, 1 # i += 1<br />
j Loop<br />
Exit:<br />
Instruções Instru ões para tomada <strong>de</strong> <strong>de</strong>cisões<br />
• Testes <strong>de</strong> igualda<strong>de</strong> em assembly MIPS<br />
– Operadores constantes são populares nas comparações<br />
– Como o registrador $zero sempre tem 0, po<strong>de</strong>-se<br />
comparar com zero; para comparar com outros valores,<br />
existe uma versão com en<strong>de</strong>reçamento imediato da<br />
instrução slt:<br />
slti $t0, $s2, 10 # $t0 =1 se $s2 < 10<br />
• Interface hardware/software<br />
– Os compiladores MIPS utilizam as instruções slt, slti,<br />
beq, bne e o valor fixo 0 para criar todas as condições<br />
relativas: igual, diferente, menor que, menor ou<br />
igual,maior que, maior ou igual<br />
– Assim, as construções lógicas <strong>de</strong> linguagens <strong>de</strong> alto<br />
nível, como C e Java, são mapeadas em instruções<br />
assembly <strong>de</strong> <strong>de</strong>svio condicional
Conteúdo Conte do<br />
• Introdução <br />
• Operações no hardware do computador <br />
• Operandos do hardware do computador <br />
• Representando instruções no computador <br />
• Operações lógicas <br />
• Instruções para tomada <strong>de</strong> <strong>de</strong>cisões <br />
• Suporte para procedimentos no hardware do computador<br />
• Comunicando-se com as pessoas<br />
• En<strong>de</strong>reçamento no MIPS para operados imediatos e en<strong>de</strong>reços <strong>de</strong> 32<br />
bits<br />
• Traduzindo e iniciando um programa<br />
• Como os compiladores otimizam<br />
• Um exemplo <strong>de</strong> or<strong>de</strong>nação na linguagem C para juntar tudo isso<br />
• Arrays versus ponteiros<br />
• Vida real: instruções do IA-32<br />
• Falácias e armadilhas<br />
• Leituras e exercícios<br />
Suporte para procedimentos<br />
• O software do MIPS utiliza a seguinte convenção<br />
na alocação <strong>de</strong> seus 32 registradores para<br />
chamada <strong>de</strong> procedimentos:<br />
– $a0 - $a3: quatro registradores <strong>de</strong> argumento, para<br />
passar parâmetros;<br />
– $v0 - $v1: dois registradores <strong>de</strong> valor, para valores <strong>de</strong><br />
retorno<br />
– $ra: um registrador <strong>de</strong> en<strong>de</strong>reço <strong>de</strong> retorno, para<br />
retornar ao ponto <strong>de</strong> origem do programa que efetuou a<br />
chamada<br />
– Além <strong>de</strong> alocar esses registradores, o assembly do MIPS<br />
inclui uma instrução apenas para os procedimentos: ela<br />
<strong>de</strong>svia para um en<strong>de</strong>reço e simultaneamente salva o<br />
en<strong>de</strong>reço da instrução seguinte no registrador $ra<br />
(instrução jump-and-link)<br />
Suporte a procedimentos no hardware<br />
• Usando mais registradores<br />
– Suponha que um compilador precise <strong>de</strong> mais<br />
registradores para um procedimento do que os quatro<br />
disponíveis: utiliza-se a pilha (stack)<br />
• Pilha<br />
– Estrutura <strong>de</strong> dados – fila em que o último que entra é o<br />
primeiro que sai<br />
– Stack pointer é ajustado em uma word para cada<br />
registrador salvo ou restaurado<br />
• Push insere itens<br />
• Pop remove itens<br />
– O MIPS tem o registrador $sp, stack pointer, usado para<br />
salvar os registradores necessários pelo procedimento<br />
chamado<br />
– As pilhas crescem <strong>de</strong> en<strong>de</strong>reços maiores para menores<br />
Suporte para procedimentos<br />
• Procedimentos ou funções<br />
– construções das linguagens <strong>de</strong> programação que<br />
servem para estruturar programas, tornando-os mais<br />
fáceis <strong>de</strong> enten<strong>de</strong>r, <strong>de</strong>purar e reutilizar<br />
– Seis etapas<br />
1. Colocar parâmetros em um lugar on<strong>de</strong> o procedimento possa<br />
acessá-lo<br />
2. Transferir o controle para o procedimento<br />
3. Adquirir os recursos <strong>de</strong> armazenamento necessários para o<br />
procedimento<br />
4. Realizar a tarefa <strong>de</strong>sejada<br />
5. Colocar o valor <strong>de</strong> retorno em um local on<strong>de</strong> o programa que<br />
o chamou possa acessá-lo<br />
6. Retornar o controle para o ponto <strong>de</strong> origem , pois um<br />
procedimento po<strong>de</strong> ser chamado <strong>de</strong> vários pontos <strong>de</strong> um<br />
programa<br />
Suporte a procedimentos no hardware<br />
• Instrução jump-and-link (jal)<br />
– Jal En<strong>de</strong>recoProcedimento<br />
– O “link” é armazenado no registrador $ra, <strong>de</strong>nominado en<strong>de</strong>reço<br />
<strong>de</strong> retorno<br />
– Implícita na idéia <strong>de</strong> programa armazenado é a necessida<strong>de</strong> <strong>de</strong> ter<br />
um registrador para manter o en<strong>de</strong>reço da instrução atual que está<br />
sendo executada, chamado <strong>de</strong> contador <strong>de</strong> programa ou PC<br />
(program counter)<br />
– A instrução jal salva PC+4 no registrador $ra para o link com a<br />
instrução seguinte, a fim <strong>de</strong> preparar o retorno do procedimento<br />
– Para apoiar tais situações, computadores como o MIPS utilizam<br />
uma instrução <strong>de</strong> jump register (jr), significando um <strong>de</strong>svio<br />
incondicional para o en<strong>de</strong>reço especificado no registrador:<br />
Jr $ra<br />
– Assim, o programa que chama o procedimento, coloca os valores<br />
<strong>de</strong> parâmetro em $a0 - $a3 e utiliza jal X par <strong>de</strong>sviar para o<br />
procedimento X.<br />
– O procedimento X realiza as suas operações, coloca os resultados<br />
em $v0 - $v1 e retorna o controle para o caller usando jr $ra<br />
Suporte a procedimentos no hardware<br />
• Compilando um procedimento em C<br />
int exemplo_folha (int g, int h, int i, int j){<br />
int f;<br />
f = ( g + h ) – ( i + j );<br />
Return f;<br />
}<br />
– As variáveis <strong>de</strong> parâmetro g, h, i e j correspon<strong>de</strong>m ao registradores<br />
<strong>de</strong> argumento $a0 - $a3 e f correspon<strong>de</strong> a $s0<br />
exemplo_folha:<br />
addi $sp, $sp, -12 # ajusta a pilha (3<br />
itens)<br />
sw $t1, 8($sp) # salva registrador<br />
sw $t0, 4($sp) # salva registrador<br />
sw $s0, 0($sp) # salva registrador
Suporte a procedimentos no hardware<br />
exemplo_folha:<br />
addi $sp, $sp, -12 # ajusta a pilha (3 itens)<br />
sw $t1, 8($sp) # salva registrador<br />
sw $t0, 4($sp) # salva registrador<br />
sw $s0, 0($sp) # salva registrador<br />
add $t0, $a0, $a1 # $t0 contém g+h<br />
add $t1, $a2, $a3 # $t1 contém i+j<br />
sub $s0, $t0, $t1 # f = (g+h) – (i+j)<br />
add $v0, $s0, $zero # copia f para reg. <strong>de</strong> retorno<br />
Suporte a procedimentos no hardware<br />
• O software do MIPS separa 18 dos registradores<br />
em dois grupos (convenção)<br />
– $t0-$t9: 10 registradores temporários que não são<br />
preservados pelo procedimento chamado<br />
– $s0-$s7: 8 registradores que precisam ser preservados<br />
em uma chamada (se forem usados, o procedimento<br />
chamado os salva e restaura)<br />
• Procedimentos aninhados<br />
– A solução é empilhar os valores dos registradores que<br />
vão ser utilizados<br />
• Código que chama: empilha $a?, $t?<br />
• Procedimento chamado: empilha $ra e registradores usados por<br />
ele<br />
• Resumo: sempre é interessante empilhar registradores usados<br />
pelo procedimento<br />
Suporte a procedimentos no hardware<br />
• Interface hardware/software<br />
– Uma variável em C é um local na memória, e sua interpretação<br />
<strong>de</strong>pen<strong>de</strong> tanto do seu tipo quanto da classe <strong>de</strong> armazenamento<br />
– A linguagem C possui duas classes <strong>de</strong> armazenamento: estáticas e<br />
automáticas<br />
– As variáveis automáticas são locais a um procedimento e são<br />
<strong>de</strong>scartadas quando o procedimento termina.<br />
– As variáveis estáticas permanecem durante entradas e saídas <strong>de</strong><br />
procedimento<br />
– As variáveis C <strong>de</strong>claradas fora <strong>de</strong> procedimentos são consi<strong>de</strong>radas<br />
estáticas, assim como as variáveis <strong>de</strong>claradas <strong>de</strong>ntro <strong>de</strong><br />
procedimento com a palavra reservada static<br />
– Para simplificar o acesso aos dados estáticos, o software do MIPS<br />
reserva outro registrador, chamado <strong>de</strong> ponteiro global, e<br />
referenciado como $gp<br />
– $gp é um ponteiro global que referencia a memória para facilitar o<br />
acesso através <strong>de</strong> operações simples <strong>de</strong> load e store.<br />
Suporte a procedimentos no hardware<br />
• Preparando o retorno<br />
exemplo_folha:<br />
addi $sp, $sp, -12 # ajusta a pilha (3 itens)<br />
sw $t1, 8($sp) # salva registrador<br />
sw $t0, 4($sp) # salva registrador<br />
sw $s0, 0($sp) # salva registrador<br />
add $t0, $a0, $a1 # $t0 contém g+h<br />
add $t1, $a2, $a3 # $t1 contém i+j<br />
sub $s0, $t0, $t1 # f = (g+h) – (i+j)<br />
add $v0, $s0, $zero # copia f para reg. <strong>de</strong> retorno<br />
lw $s0, 0($sp)<br />
lw $t0, 4($sp)<br />
lw St1, 8($sp)<br />
addi $sp, $sp, 12 # exclui 3 itens da pilha<br />
jr $ra<br />
Suporte a procedimentos no hardware<br />
int fact (int n){<br />
if (n < 1) return(1);<br />
else return (n * fact(n-1));<br />
}<br />
fact:<br />
addi $sp, $sp, -8 # ajusta pilha para 2 itens<br />
sw $ra, 4($sp) # salva en<strong>de</strong>reço <strong>de</strong> retorno<br />
sw $a0, 0($sp) # salva o argumento n<br />
slti $t0, $a0, 1 # teste para n < 1<br />
beq $t0, $zero, L1 # se n>= 1, <strong>de</strong>svia para L1<br />
addi $v0, $zero, 1 # prepara o “retorna 1”<br />
addi $sp, $sp, 8 # retira dois itens da pilha<br />
jr $ra # retorna<br />
L1:<br />
addi $a0,$a0, -1 # argumento recebe n-1<br />
jal fact # chama fact com n-1<br />
lw $a0, 0($sp) # retorna <strong>de</strong> jal: restaura o arg. N<br />
lw $ra, 4($sp) # restaura o en<strong>de</strong>reço <strong>de</strong> retorno<br />
addi $sp, $sp, 8 # ajusta pilha para remover 2 itens<br />
mul $v0, $a0, $v0 # calcula n * fact(n-1)<br />
jr $ra # retorna para o procedimento que chamou<br />
Suporte a procedimentos no hardware<br />
• Reservando espaço para novos dados na pilha<br />
– A pilha também é utilizada para armazenar variáveis<br />
que são locais ao procedimento, que não cabem nos<br />
registradores, como arrays ou estruturas locais<br />
– O segmento da pilha que contém todos os registradores<br />
salvos e as variáveis locais <strong>de</strong> um procedimento é<br />
chamado <strong>de</strong> frame <strong>de</strong> procedimento ou registro <strong>de</strong> ativação
Suporte a procedimentos no hardware<br />
• Reservando espaço para novos dados no heap<br />
– Além <strong>de</strong> variáveis que são locais ao procedimentos,<br />
programadores precisam <strong>de</strong> espaço para variáveis<br />
estáticas e para estrutura <strong>de</strong> dados dinâmicas<br />
Conteúdo Conte do<br />
O segmento <strong>de</strong> um<br />
arquivo-objeto Unix que<br />
contém o código em<br />
linguagem <strong>de</strong> máquina<br />
para as rotinas do<br />
arquivo-fonte<br />
• Introdução <br />
• Operações no hardware do computador <br />
• Operandos do hardware do computador <br />
• Representando instruções no computador <br />
• Operações lógicas <br />
• Instruções para tomada <strong>de</strong> <strong>de</strong>cisões <br />
• Suporte para procedimentos no hardware do computador <br />
• Comunicando-se com as pessoas<br />
• En<strong>de</strong>reçamento no MIPS para operados imediatos e en<strong>de</strong>reços <strong>de</strong> 32<br />
bits<br />
• Traduzindo e iniciando um programa<br />
• Como os compiladores otimizam<br />
• Um exemplo <strong>de</strong> or<strong>de</strong>nação na linguagem C para juntar tudo isso<br />
• Vida real: instruções do IA-32<br />
• Falácias e armadilhas<br />
• Comentários finais<br />
• Leituras e exercícios<br />
Comunicando-se Comunicando se com as pessoas<br />
• Compilando um procedimento <strong>de</strong> cópia <strong>de</strong> string<br />
para <strong>de</strong>monstrar o uso <strong>de</strong> strings em C<br />
void strcpy(char x[], char y[]){<br />
int i;<br />
i = 0;<br />
}<br />
while ( (x[i] = y[i]) != ‘\0’)<br />
i += 1;<br />
– Consi<strong>de</strong>rando que os en<strong>de</strong>reços base para os arrays x e<br />
y são encontrados em $a0 e $a1<br />
strcpy:<br />
addi $sp, $sp, -4<br />
sw $s0, 0($sp)<br />
add $s0, $zero, $zero<br />
L1:<br />
Suporte a procedimentos no hardware<br />
• Reservando espaço para novos dados no heap<br />
– A forma <strong>de</strong> reservar memória permite que a pilha e o<br />
heap cresçam um em direção ao outro, permitindo o uso<br />
eficiente da memória enquanto os dois segmentos<br />
aumentam e diminuem<br />
– A forma pela qual os en<strong>de</strong>reços são usados são<br />
convenções do software e não fazem parte da<br />
arquitetura MIPS<br />
– A linguagem C aloca e libera espaço no heap com<br />
funções explícitas<br />
• malloc(): aloca espaço no heap<br />
• free(): libera espaço no heap<br />
Comunicando-se Comunicando se com as pessoas<br />
• Representação <strong>de</strong> caracteres<br />
– Código ASCII <strong>de</strong> 8 bits<br />
– Computadores necessitam <strong>de</strong> instruções que realizem a<br />
movimentação <strong>de</strong> grupos <strong>de</strong> bits <strong>de</strong> palavras<br />
lb $t0, 0($sp)<br />
Sb $t0, 0($sp)<br />
– Caracteres são representados por conjuntos <strong>de</strong> strings,<br />
com geralmente três opções para representação:<br />
• A primeira posição da string é reservada para indicar o tamnho<br />
<strong>de</strong> uma string;<br />
• Uma variável acompanhante possui o tamanho da string (como<br />
uma estrutura);<br />
• A última posição da string é ocupada por um caractere que<br />
serve para marcar o final da string ( ‘\0’ na linguagem C; ‘$’<br />
x86)<br />
Comunicando-se Comunicando se com as pessoas<br />
strcpy:<br />
addi $sp, $sp, -4<br />
sw $s0, 0($sp)<br />
add $s0, $zero, $zero<br />
L1: add $t1, $s0, $a1 # en<strong>de</strong>reço <strong>de</strong> y[i] em $t1<br />
lb $t2, 0($t1) # $t2 = y[i], como é um byte,<br />
não i * 4<br />
add $t3, $s0, $a0 # en<strong>de</strong>reço <strong>de</strong> x[i] em $t3<br />
sb $t2, 0($t3) # x[i] = y[i]<br />
beq $t2, $zero, L2 # se y[i]== 0 , vai para L2<br />
addi $s0, $s0, 1 # i = i + 1<br />
j L1<br />
L2: lw $s0, 0 ($sp)<br />
addi $sp, $sp, 4<br />
jr $ra
Comunicando-se Comunicando se com as pessoas<br />
• Caracteres e strings em Java<br />
– Unico<strong>de</strong> é uma codificação universal dos alfabetos da<br />
maior parte das linguagens humanas<br />
– 16 bits para representar um caractere<br />
lh $t0, 0($sp)<br />
sh $t0, 0($sp)<br />
– Ao contrário da linguagem C, Java reserva uma word<br />
para indicar o tamanho da string<br />
En<strong>de</strong>reçamento En<strong>de</strong>re amento no MIPS para imediatos<br />
• En<strong>de</strong>reçamento no MIPS para operandos<br />
imediatos e en<strong>de</strong>reços <strong>de</strong> 32 bits<br />
– Embora manter todas as instruções com 32 bits <strong>de</strong><br />
tamanho seja interessante, em certas situações é<br />
conveniente ter uma constante <strong>de</strong> 32 bits ou en<strong>de</strong>reços<br />
<strong>de</strong> 32 bits<br />
– Embora as constantes na maioria das vezes sejam curtas<br />
e caibam em um campo <strong>de</strong> 16 bits, às vezes elas são<br />
maiores<br />
– O conjunto <strong>de</strong> instruções MIPS inclui a instrução load<br />
upper immediate (lui) especificamente para atribuir os 16<br />
bits mais altos <strong>de</strong> uma constante a um registrador,<br />
permitindo que uma instrução subseqüente atribua os<br />
16 bits mais baixos <strong>de</strong> uma constante<br />
– Exemplo lui $t0, 255<br />
En<strong>de</strong>reçamento En<strong>de</strong>re amento MIPS para imediatos<br />
• Desvios condicionais e jumps<br />
– 26 bits são alocados para o campo <strong>de</strong> en<strong>de</strong>reço (32 – 6)<br />
– Em <strong>de</strong>svios condicionais, é necessário especificar dois<br />
operandos além do en<strong>de</strong>reço <strong>de</strong> <strong>de</strong>svio: 6 bits <strong>de</strong><br />
opco<strong>de</strong>, 5 bits para registrador, 5 bits para registrador,<br />
16 bits para en<strong>de</strong>reço<br />
– Se os en<strong>de</strong>reços do programa tivessem que caber nesse<br />
campo <strong>de</strong> 16 bits, nenhum programa po<strong>de</strong>ria ser maior<br />
que 2**16<br />
– Uma alternativa seria especificar um registrador que<br />
sempre seria somado ao en<strong>de</strong>reço <strong>de</strong> <strong>de</strong>svio, <strong>de</strong> mo<strong>de</strong><br />
que uma instrução <strong>de</strong> <strong>de</strong>svio pu<strong>de</strong>sse calcular o<br />
seguinte:<br />
• Contador <strong>de</strong> programa = Registrador + en<strong>de</strong>reço <strong>de</strong> <strong>de</strong>svio<br />
Conteúdo Conte do<br />
• Introdução <br />
• Operações no hardware do computador <br />
• Operandos do hardware do computador <br />
• Representando instruções no computador <br />
• Operações lógicas <br />
• Instruções para tomada <strong>de</strong> <strong>de</strong>cisões <br />
• Suporte para procedimentos no hardware do computador <br />
• Comunicando-se com as pessoas <br />
• En<strong>de</strong>reçamento no MIPS para operados imediatos e en<strong>de</strong>reços <strong>de</strong> 32<br />
bits<br />
• Traduzindo e iniciando um programa<br />
• Como os compiladores otimizam<br />
• Um exemplo <strong>de</strong> or<strong>de</strong>nação na linguagem C para juntar tudo isso<br />
• Vida real: instruções do IA-32<br />
• Falácias e armadilhas<br />
• Comentários finais<br />
• Leituras e exercícios<br />
En<strong>de</strong>reçamento En<strong>de</strong>re amento no MIPS para imediatos<br />
• Carregando uma constante <strong>de</strong> 32 bits<br />
– Qual é o código em assembly do MIPS para carregar<br />
esta constante <strong>de</strong> 32 bits no registrador $s0?<br />
– 0000 0000 0011 1101 0000 1001 0000 0000<br />
lui $s0, 61<br />
ori $s0, $s0, 2304<br />
• En<strong>de</strong>reçamento em <strong>de</strong>svios condicionais e jumps<br />
– As instruções <strong>de</strong> jump no MIPS possuem o<br />
en<strong>de</strong>reçamento mais simples possível. Elas utilizam o<br />
último formato <strong>de</strong> instruções do MIPS, chamado <strong>de</strong> J,<br />
que consiste em 6 bits para o campo <strong>de</strong> operação e o<br />
restante dos bits para o campo <strong>de</strong> en<strong>de</strong>reço<br />
En<strong>de</strong>reçamento En<strong>de</strong>re amento do MIPS para <strong>de</strong>svios<br />
• Desvios condicionais<br />
– Qual registrador usar?<br />
– A resposta vem da observação <strong>de</strong> como os <strong>de</strong>svios<br />
condicionais são usados<br />
– Os <strong>de</strong>svios condicionais são encontrados em loops e em<br />
instruções if, <strong>de</strong> modo que costumam <strong>de</strong>sviar para uma<br />
instrução próxima.<br />
– Por exemplo, cerca <strong>de</strong> meta<strong>de</strong> <strong>de</strong> todos os <strong>de</strong>svios<br />
condicionais nos benchmarks SPEC2000 vão para locais a<br />
menos <strong>de</strong> 16 instruções<br />
– Como o contador <strong>de</strong> instruções contém o en<strong>de</strong>reço da<br />
instrução atual, po<strong>de</strong>mos <strong>de</strong>sviar em +/- 2**15 palavras<br />
da instrução atual se o usarmos o PC como registrador<br />
a ser somado ao en<strong>de</strong>reço.
En<strong>de</strong>reçamento En<strong>de</strong>re amento no MIPS para <strong>de</strong>svios<br />
• Desvios condicionais<br />
– Essa forma <strong>de</strong> en<strong>de</strong>reçamento é <strong>de</strong>nominada<br />
en<strong>de</strong>reçamento relativo ao PC<br />
– Como na maioria dos computadores atuais, o MIPS<br />
utiliza o en<strong>de</strong>reçamento relativo ao PC para todos os<br />
<strong>de</strong>svios condicionais.<br />
– Instruções JAL chamam procedimentos que não tem<br />
motivos para estarem próximas à instrução atual: a<br />
arquitetura MIPS utiliza o formato longo (J) para<br />
instruções <strong>de</strong> chamada <strong>de</strong> procedimento<br />
– Como todas as instruções tem tamanho <strong>de</strong> 4 bytes, o<br />
MIPS aumenta o alcance do en<strong>de</strong>reçamento<br />
interpretando o campo <strong>de</strong> en<strong>de</strong>reçamento relativo a<br />
word, e não ao byte: assim, o campo <strong>de</strong> 16 bits po<strong>de</strong> se<br />
<strong>de</strong>sviar para uma distância quatro vezes maior; da<br />
mesma forma, o campo <strong>de</strong> 28 bits nas instruções <strong>de</strong><br />
jump também en<strong>de</strong>reçam words.<br />
En<strong>de</strong>reçamento En<strong>de</strong>re amento <strong>de</strong> <strong>de</strong>svios no MIPS<br />
80000<br />
80004<br />
80008<br />
80012<br />
80016<br />
80020<br />
0<br />
0<br />
35<br />
5<br />
8<br />
2<br />
9<br />
9<br />
8<br />
19<br />
19<br />
22<br />
8<br />
21<br />
19<br />
En<strong>de</strong>reçamento En<strong>de</strong>re amento no MIPS<br />
• Interface<br />
hardware/software<br />
– Embora as instruções<br />
estudadas tem 32 bits em<br />
tamanho, a arquitetura<br />
MIPS tem extensões <strong>de</strong> 64<br />
bits, em resposta a<br />
necessida<strong>de</strong> <strong>de</strong> software<br />
para programas maiores<br />
• Uma única instrução po<strong>de</strong><br />
trabalhar com modos <strong>de</strong><br />
en<strong>de</strong>reçamento diferentes:<br />
0<br />
9<br />
9<br />
2000<br />
4<br />
0<br />
0<br />
2<br />
1<br />
0<br />
32<br />
En<strong>de</strong>reçamento En<strong>de</strong>re amento <strong>de</strong> <strong>de</strong>svios no MIPS<br />
• Exemplo<br />
– Se consi<strong>de</strong>rarmos que o loop inicia na posição <strong>de</strong><br />
memória 80000, qual é o código <strong>de</strong> máquina para esse<br />
loop?<br />
loop: sll $t1, $s3, 2 # $t1 = 4 * i<br />
add $t1, $t1, $s6 # $t1 = en<strong>de</strong>reço <strong>de</strong> save[i]<br />
lw $t0, 0($t1) #$t0 = save[i]<br />
bne $t0, $s5, Exit # vá para Exit se save[i] k<br />
addi $s3, $s3, 1 # i += 1<br />
j Loop<br />
Exit:<br />
En<strong>de</strong>reçamento En<strong>de</strong>re amento no MIPS<br />
• Resumo dos modos <strong>de</strong> en<strong>de</strong>reçamento<br />
– En<strong>de</strong>reçamento <strong>de</strong> registrador: on<strong>de</strong> o operando é um<br />
registrador;<br />
– En<strong>de</strong>reçamento <strong>de</strong> base e <strong>de</strong>slocamento: on<strong>de</strong> o<br />
operando está no local <strong>de</strong> memória cujo en<strong>de</strong>reço é a<br />
soma <strong>de</strong> um registrador e uma constante <strong>de</strong> instrução<br />
– En<strong>de</strong>reçamento imediato: on<strong>de</strong> o operando é uma<br />
constante <strong>de</strong>ntro da própria instrução<br />
– En<strong>de</strong>reçamento relativo ao PC: on<strong>de</strong> o en<strong>de</strong>reçamento é<br />
a soma do PC e uma constante na instrução<br />
– En<strong>de</strong>reçamento pseudodireto: on<strong>de</strong> o en<strong>de</strong>reço <strong>de</strong> jump<br />
são os 26 bits da instrução concatenados com os bits<br />
mais altos do PC<br />
Conteúdo Conte do<br />
• Introdução <br />
• Operações no hardware do computador <br />
• Operandos do hardware do computador <br />
• Representando instruções no computador <br />
• Operações lógicas <br />
• Instruções para tomada <strong>de</strong> <strong>de</strong>cisões <br />
• Suporte para procedimentos no hardware do computador <br />
• Comunicando-se com as pessoas <br />
• En<strong>de</strong>reçamento no MIPS para operados imediatos e en<strong>de</strong>reços <strong>de</strong> 32<br />
bits <br />
• Traduzindo e iniciando um programa<br />
• Como os compiladores otimizam<br />
• Um exemplo <strong>de</strong> or<strong>de</strong>nação na linguagem C para juntar tudo isso<br />
• Vida real: instruções do IA-32<br />
• Falácias e armadilhas<br />
• Comentários finais<br />
• Leituras e exercícios
Traduzindo e iniciando um programa<br />
• Hierarquia <strong>de</strong> tradução<br />
para a linguagem C<br />
– Um programa em alto<br />
nível é inicialmente<br />
compilado para um<br />
programa em assembly, e<br />
<strong>de</strong>pois montado em um<br />
módulo objeto em<br />
linguagem <strong>de</strong> máquina.<br />
O link-editor combina os<br />
vários módulos com as<br />
rotinas <strong>de</strong> biblioteca<br />
para resolver todas as<br />
referências. O loa<strong>de</strong>r,<br />
então, coloca o código<br />
<strong>de</strong> máquina nos locais<br />
apropriados em<br />
memória, para ser<br />
executado pelo<br />
processador.<br />
Traduzindo e iniciando um programa<br />
• Arquivo objeto em sistemas UNIX<br />
– Cabeçalho: <strong>de</strong>screve o tamanho e posições das outras<br />
partes do código<br />
– Segmento <strong>de</strong> texto: código em linguagem <strong>de</strong> máquina<br />
– Segmento <strong>de</strong> dados: contém os dados alocados por toda<br />
a vida do programa (dados estáticos)<br />
– Informações <strong>de</strong> relocação: i<strong>de</strong>ntificam instruções e<br />
words que <strong>de</strong>pen<strong>de</strong>m <strong>de</strong> en<strong>de</strong>reços absolutos quando o<br />
programa é carregado na memória<br />
– Tabela <strong>de</strong> símbolos: contém os rótulos restantes que não<br />
estão <strong>de</strong>finidos, como referências externas<br />
– Informações <strong>de</strong> <strong>de</strong>puração<br />
Conteúdo Conte do<br />
• Introdução <br />
• Operações no hardware do computador <br />
• Operandos do hardware do computador <br />
• Representando instruções no computador <br />
• Operações lógicas <br />
• Instruções para tomada <strong>de</strong> <strong>de</strong>cisões <br />
• Suporte para procedimentos no hardware do computador <br />
• Comunicando-se com as pessoas <br />
• En<strong>de</strong>reçamento no MIPS para operados imediatos e en<strong>de</strong>reços <strong>de</strong> 32<br />
bits <br />
• Traduzindo e iniciando um programa <br />
• Como os compiladores otimizam<br />
• Um exemplo <strong>de</strong> or<strong>de</strong>nação na linguagem C para juntar tudo isso<br />
• Vida real: instruções do IA-32<br />
• Falácias e armadilhas<br />
• Comentários finais<br />
• Leituras e exercícios<br />
Traduzindo e iniciando um programa<br />
• Compilador<br />
– O compilador transforma o programa C em um programa em<br />
assembly, uma forma simbólica daquilo que a máquina enten<strong>de</strong>.<br />
• Montador<br />
– As arquiteturas aceitam a programação em pseudo-instruções e<br />
mnemônicos, que são convertidos em linguagem <strong>de</strong> máquina pelo<br />
montador<br />
– O montador transforma o programa assembly em um arquivo<br />
objeto, que é uma combinação <strong>de</strong> instruções em linguagem <strong>de</strong><br />
máquina, dados e informações necessárias para colocar instruções<br />
na memória<br />
– Para produzir a versão binária das instruções, precisa <strong>de</strong>terminar<br />
os en<strong>de</strong>reços <strong>de</strong> todos os rótulos - os montadores registram os<br />
rótulos utilizados nos <strong>de</strong>svios e nas instruções <strong>de</strong> transferência <strong>de</strong><br />
dados por meio <strong>de</strong> uma tabela <strong>de</strong> símbolos, que contém pares <strong>de</strong><br />
símbolo e en<strong>de</strong>reço<br />
Traduzindo e iniciando um programa<br />
• Linkeditor (link-edição)<br />
– Colocar os módulos <strong>de</strong> código e dados simbolicamente na<br />
memória<br />
– Determinar os en<strong>de</strong>reços <strong>de</strong> rótulos <strong>de</strong> dados e instruções<br />
– Remendar referências internas e externas<br />
– O linkeditor produz um arquivo executável, que tem o mesmo<br />
formato do arquivo objeto, exceto que não tem referências não<br />
resolvidas<br />
– Linkedição estática x dinâmica<br />
– Desvantagens da linkedição estática:<br />
• Rotinas <strong>de</strong> biblioteca fazem parte do código e não po<strong>de</strong>m ser<br />
atualizadas<br />
• Carrega a biblioteca inteira, mesmo se parte da biblioteca nunca seja<br />
chamada<br />
– Desvantagens da linkedição dinâmica:<br />
• Execução dos programas po<strong>de</strong> se tornar mais lenta<br />
• Erros <strong>de</strong> execução em programas que necessitam <strong>de</strong> bibliotecas<br />
dinâmicas não existentes.<br />
Como os compiladores otimizam<br />
• Compiladores<br />
– Construídos consi<strong>de</strong>rando um conjunto <strong>de</strong> fases <strong>de</strong><br />
otimização<br />
– Otimização: espaço <strong>de</strong> armazenamento e velocida<strong>de</strong> <strong>de</strong><br />
execução
Como os compiladores otimizam<br />
• Compilador<br />
– Afeta significantemente o <strong>de</strong>sempenho dos programas<br />
– Transformação <strong>de</strong> alto nível: procedimentos inline<br />
– Loop unrolling – <strong>de</strong>sdobramento <strong>de</strong> loops<br />
•for (i = 0; i < 100; i++) g ();<br />
• Depois do loop unrolling.<br />
•for (i = 0; i < 100; i += 2) { g (); g (); }<br />
– Otimizações<br />
• Otimizações locais atuam <strong>de</strong>ntro <strong>de</strong> um bloco básico<br />
• Otimizações globais atuam entre blocos básicos<br />
• Alocação <strong>de</strong> registradores<br />
Como os compiladores otimizam<br />
• Otimizações globais<br />
– Movimentação <strong>de</strong><br />
código<br />
• Encontra código<br />
que é invariante<br />
no loop; um<br />
trecho que<br />
código que<br />
calcula o mesmo<br />
valor,<br />
in<strong>de</strong>pen<strong>de</strong>nte da<br />
iteração corrente<br />
do loop;<br />
– Eliminação <strong>de</strong><br />
variável <strong>de</strong><br />
indução<br />
• É um<br />
combinação <strong>de</strong><br />
transformações<br />
que reduz o<br />
trabalho na<br />
in<strong>de</strong>xação <strong>de</strong><br />
arrays<br />
Exemplo <strong>de</strong> or<strong>de</strong>nação or<strong>de</strong>na ão na linguagem C<br />
• O procedimento swap<br />
void swap(int v[], int k){<br />
int temp;<br />
temp = v[k];<br />
v[k] = v[k+1];<br />
v[k+1] = temp;<br />
}<br />
sll $t1, $a1, 2 # registrador $t1 = k * 4<br />
add $t1, $a0, $t1 # $t1 = v + (k*4)<br />
lw $t0, 0($t1) # $t0 = v[k] (temp)<br />
lw $t2, 4($t1) # $t2 = v[k+1];<br />
sw $t2, 0($t0) # v[k] = registrador $t2<br />
sw $t0, 4($t1) # v[k+1] = registrador $t0 (temp)<br />
Como os compiladores otimizam<br />
• Otimizações locais<br />
– Eliminação <strong>de</strong> sub-expressões comuns<br />
• x[i] = x[i] + 4<br />
• O cálculo do en<strong>de</strong>reço <strong>de</strong> x[] ocorre duas vezes<br />
– Outras otimizações<br />
• Redução <strong>de</strong> força: substitui operações complexas por outras mais<br />
simples, por exemplo um mult por um <strong>de</strong>slocamento à esquerda<br />
• Propagação <strong>de</strong> constante: encontram constantes no código e as<br />
propagam, encolhendo os valores <strong>de</strong> constante sempre que possível<br />
• Propagação <strong>de</strong> cópia: propaga valores que são cópias simples,<br />
eliminando a necessida<strong>de</strong> <strong>de</strong> ler valores<br />
• Eliminação <strong>de</strong> local <strong>de</strong> armazenamento: encontra locais com<br />
armazenamento não utilizados<br />
• Eliminação <strong>de</strong> código morto: encontra fragmentos <strong>de</strong> código que nunca<br />
são utilizados – código morto ocorre com bastante freqüência.<br />
Conteúdo Conte do<br />
• Introdução <br />
• Operações no hardware do computador <br />
• Operandos do hardware do computador <br />
• Representando instruções no computador <br />
• Operações lógicas <br />
• Instruções para tomada <strong>de</strong> <strong>de</strong>cisões <br />
• Suporte para procedimentos no hardware do computador <br />
• Comunicando-se com as pessoas <br />
• En<strong>de</strong>reçamento no MIPS para operados imediatos e en<strong>de</strong>reços <strong>de</strong> 32<br />
bits <br />
• Traduzindo e iniciando um programa <br />
• Como os compiladores otimizam <br />
• Um exemplo <strong>de</strong> or<strong>de</strong>nação na linguagem C para juntar tudo isso<br />
• Vida real: instruções do IA-32<br />
• Falácias e armadilhas<br />
• Comentários finais<br />
• Leituras e exercícios<br />
Exemplo <strong>de</strong> or<strong>de</strong>nação or<strong>de</strong>na ão na linguagem C<br />
• O procedimento swap completo<br />
swap:<br />
sll $t1, $a1, 2 # registrador $t1 = k * 4<br />
add $t1, $a0, $t1 # $t1 = v + (k*4)<br />
lw $t0, 0($t1) # $t0 = v[k] (temp)<br />
lw $t2, 4($t1) # $t2 = v[k+1];<br />
sw $t2, 0($t0) # v[k] = registrador $t2<br />
sw $t0, 4($t1) # v[k+1] = registrador $t0 (temp)<br />
jr $ra
Exemplo <strong>de</strong> or<strong>de</strong>nação or<strong>de</strong>na ão na linguagem C<br />
• O procedimento sort<br />
void sort(int v[], int n){<br />
int i, j;<br />
for(i=0; i < n; i++){<br />
for(j=i-1; j >=0 && v[j] > v[j+1]; j --){<br />
swap(v,j);<br />
}<br />
}<br />
• Alocação <strong>de</strong> registradores para sort<br />
– Os dois parâmetros do procedimento sort, v e n, estão<br />
nos registradores <strong>de</strong> parâmetro $a0 e $a1, e alocamos o<br />
registrador $s0 a i e o registrador $1 a j<br />
Exemplo <strong>de</strong> or<strong>de</strong>nação or<strong>de</strong>na ão da linguagem C<br />
• Código para o procedimento sort (segundo loop)<br />
– for(j=i-1; j >=0 && v[j] > v[j+1]; j --)<br />
– Teste <strong>de</strong> loop composto <strong>de</strong> duas partes:<br />
• J >-0<br />
• V[j] > v[j+1]<br />
addi $s1, $1, -1 #j=i-1<br />
For2tst: slti $t0, $1, 0 # $t0 = 1 se j < 0<br />
bne $t0, $zero, exit2<br />
sll $t1, $s1, 2 # $t1 = j * 4<br />
add $t2, $a0, $t1 # $t2 = v + (j+4)<br />
lw $t3, 0($t2) # $t3 = v[j]<br />
lw $t4, 4($t2) # $t4 = v[j+1]<br />
slt $t0, $t4, $t3 # $t0 $t4 >= $t3<br />
beq $t0, $zero, exit2<br />
... (corpo do for 2)<br />
add $1, $1, -1 # j -= 1<br />
j for2tst<br />
exit2:<br />
Exemplo <strong>de</strong> or<strong>de</strong>nação or<strong>de</strong>na ão em C<br />
• Preservando registradores em sort<br />
– Deve-se salvar o en<strong>de</strong>reço <strong>de</strong> retorno $ra (lembre-se que<br />
são loops aninhados)<br />
– O procedimento sort também utiliza registradores<br />
salvos, <strong>de</strong> modo que precisam ser salvos<br />
addi $sp, $sp, -20 # 5 registradores<br />
sw $ra, 16($sp) # salva $ra na pilha<br />
sw $s3, 12($sp) # sala $s3 na pilha<br />
sw $s2, 8($sp)<br />
sw $s1, 4($sp)<br />
sw $s0, 0($sp)<br />
– Ao final do procedimento, os registradores <strong>de</strong>vem ser<br />
restaurados na or<strong>de</strong>m inversa<br />
Exemplo <strong>de</strong> or<strong>de</strong>nação or<strong>de</strong>na ão na linguagem C<br />
• Código para o procedimento sort (primeiro loop)<br />
– loops são compostos <strong>de</strong> 3 partes:<br />
• Inicialização das variáveis <strong>de</strong> controle<br />
• Teste da condição <strong>de</strong> controle<br />
• Incremento da variável <strong>de</strong> controle<br />
move $s0, $zero #i=0<br />
For1tst: slt $t0, $s0, $a1<br />
beq $t0, $zero, exit1<br />
...<br />
addi $s0, S0,1<br />
j for1slt<br />
exit1<br />
Exemplo <strong>de</strong> or<strong>de</strong>nação or<strong>de</strong>na ão em C<br />
• Chamada <strong>de</strong> procedimento em sort<br />
– swap(i,j)<br />
– jal swap<br />
• Passando parâmetros em sort<br />
– Os procedimentos sort e swap utilizam como parâmetros os<br />
registradores $a0, $a1<br />
– É necessário então salvar os registradores em $s2 e $3 antes da<br />
chamada do procedimento (melhor que salvar na pilha)<br />
• move $s2, $a0<br />
• move $s3, $a1<br />
– Depois passamos os parâmetros para swap da<br />
seguinte forma:<br />
• move $a0, $s2<br />
• move $a1, $s1<br />
Conteúdo Conte do<br />
• Introdução <br />
• Operações no hardware do computador <br />
• Operandos do hardware do computador <br />
• Representando instruções no computador <br />
• Operações lógicas <br />
• Instruções para tomada <strong>de</strong> <strong>de</strong>cisões <br />
• Suporte para procedimentos no hardware do computador <br />
• Comunicando-se com as pessoas <br />
• En<strong>de</strong>reçamento no MIPS para operados imediatos e en<strong>de</strong>reços <strong>de</strong> 32<br />
bits <br />
• Traduzindo e iniciando um programa <br />
• Como os compiladores otimizam <br />
• Um exemplo <strong>de</strong> or<strong>de</strong>nação na linguagem C para juntar tudo isso <br />
• Vida real: instruções do IA-32<br />
• Falácias e armadilhas<br />
• Comentários finais<br />
• Leituras e exercícios
Vida real: instruções instru ões do IA-32 IA 32<br />
• Os projetistas<br />
– Oferecem às vezes um conjunto <strong>de</strong> operações mais<br />
po<strong>de</strong>rosas do que aquelas encontradas no MIPS<br />
• O objetivo é reduzir o número <strong>de</strong> instruções executadas por um<br />
programa<br />
• O perigo é que essa redução po<strong>de</strong> ocorrer ao custo da<br />
simplicida<strong>de</strong>, aumentando o tempo que um programa leva<br />
para executar, pois as instruções são mais lentas.<br />
• Essa lentidão po<strong>de</strong> ser o resultado <strong>de</strong> um ciclo <strong>de</strong> clock mais<br />
lento ou a requisição <strong>de</strong> mais ciclos <strong>de</strong> clock do que uma<br />
seqüência mais simples<br />
Vida real: instruções instru ões do IA-32 IA 32<br />
• Registradores e instruções<br />
Comentários Coment rios finais<br />
• Programa armazenado<br />
– Permite a construção <strong>de</strong> máquinas <strong>de</strong> propósito geral<br />
– A seleção <strong>de</strong> um conjunto <strong>de</strong> instruções que a máquina possa<br />
enten<strong>de</strong>r exige um equilíbrio <strong>de</strong>licado entre a quantida<strong>de</strong> <strong>de</strong><br />
instruções necessárias para executar programas, a quantida<strong>de</strong> <strong>de</strong><br />
ciclos <strong>de</strong> clock por instrução e a velocida<strong>de</strong> do<br />
– Princípios <strong>de</strong> projeto:<br />
• Simplicida<strong>de</strong> favorece a regularida<strong>de</strong>: instruções <strong>de</strong> mesmo tamanho e<br />
se possível com o mesmo significado quanto aos operandos<br />
• Menor é mais rápido: o <strong>de</strong>sejo <strong>de</strong> velocida<strong>de</strong> é o motivo para que o<br />
MIPS tenha apenas 32 registradores<br />
• Torne os casos comuns mais velozes: alguns exemplos são os <strong>de</strong>svios<br />
em relação ao contador <strong>de</strong> programa e en<strong>de</strong>reçamento imediato para<br />
constantes<br />
• Um bom projeto exige bons compromissos: exemplo é o compromisso<br />
<strong>de</strong> manter todas as instruções com o mesmo tamanho frente à<br />
necessida<strong>de</strong> <strong>de</strong> representação <strong>de</strong> constantes que necessitam <strong>de</strong> mais<br />
bits para a representação<br />
Vida real: instruções instru ões do IA-32 IA 32<br />
• IA-32<br />
– Arquitetura que evoluiu ao longo do tempo, sendo produto <strong>de</strong> diferentes<br />
grupos in<strong>de</strong>pen<strong>de</strong>ntes, que modificaram a arquitetura por 20 anos,<br />
acrescentando novos recursos ao conjunto <strong>de</strong> instruções original, como<br />
alguém po<strong>de</strong>ria acrescentar roupas em uma mala pronta<br />
– Marcos importantes:<br />
• 1978: Intel 8086 – extensão do assembly para o 8080; arquitetura <strong>de</strong> 16 bits com<br />
registradores <strong>de</strong> 16 bits, com usos <strong>de</strong>dicados, ao contrário do MIPS, que tem<br />
registradores <strong>de</strong> propósito geral; en<strong>de</strong>reçamento <strong>de</strong> memória com 20 bits<br />
• 1980: coprocessador 8087 anunciado; esten<strong>de</strong> o conjunto original <strong>de</strong> instruções<br />
em 60 instruções <strong>de</strong> ponto flutuante<br />
• 1982: 80286 com en<strong>de</strong>reçamento <strong>de</strong> memória <strong>de</strong> 24 bits com um mo<strong>de</strong>lo <strong>de</strong><br />
proteção <strong>de</strong> memória<br />
• 1985: 80386, processador <strong>de</strong> 32 bits com novos modos <strong>de</strong> en<strong>de</strong>reçamento e<br />
registradores <strong>de</strong> 32 bits<br />
• 1989-95: 80486, Pentium, ...<br />
• 1997: instruções MMX nos processadores Pentium<br />
• 1999: melhorias nas instruções SIMD e oito registradores adicionais; instruções<br />
SSE (Streaming SIMD extensions)<br />
• 2001: extensões com 144 instruções adicionais para lidar com operações<br />
multimídia, exploração da computação paralela nos chips<br />
• 2003: AMD anuncia extensões arquitetônicas para aumentar o espaço <strong>de</strong><br />
en<strong>de</strong>reçamento <strong>de</strong> memória <strong>de</strong> 32 para 64 bits, alargando os registradores para<br />
64 bits<br />
Falácias Fal cias e armadilhas<br />
• Falácias<br />
– Instruções mais po<strong>de</strong>rosas significam<br />
maior <strong>de</strong>sempenho<br />
– Escreva em assembly para ter melhor<br />
<strong>de</strong>sempenho<br />
• Armadilha<br />
– Esquecer que os en<strong>de</strong>reços seqüenciais <strong>de</strong><br />
word em máquinas com en<strong>de</strong>reçamento<br />
em bytes não diferem em 1.<br />
Comentários Coment rios finais<br />
• Instruções MIPS<br />
– Cada categoria <strong>de</strong> instruções MIPS está associada a<br />
construções que aparecem nas linguagens <strong>de</strong><br />
programação<br />
• Instruções aritméticas correspon<strong>de</strong>m às operações encontradas<br />
nas instruções <strong>de</strong> atribuição<br />
• Instruções <strong>de</strong> transferência <strong>de</strong> dados provavelmente ocorrerão<br />
quando se lida com estruturas <strong>de</strong> dados, como arrays e<br />
estruturas<br />
• Os <strong>de</strong>svios condicionais são usados em instruções if e em loops<br />
• Os jumps incondicionais são usados em chamadas <strong>de</strong><br />
procedimento e retornos, e para instruções case/switch
Leituras e exercícios exerc cios<br />
• Leituras<br />
– Patterson, capítulo 2<br />
• Exercícios<br />
– Patterson, capítulo 2