19.04.2013 Views

Linguagem de Máquina - Luciano José Senger

Linguagem de Máquina - Luciano José Senger

Linguagem de Máquina - Luciano José Senger

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!