Top Banner
Conjunto de Instruções Para comandar o hardware do computador, é necessário que falemos sua língua: As palavras da linguagem de máquina são chamadas de instruções; O vocabulário forma o conjunto de instruções, que determina a interface hardware/software. Computadores com arquiteturas diferentes implementam conjuntos de instruções distintos
125

Oc2 cap03

Apr 15, 2017

Download

Engineering

RogerMasters
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Oc2 cap03

Conjunto de Instruções

Para comandar o hardware docomputador, é necessário que falemossua língua:

♦ As palavras da linguagem de máquina sãochamadas de instruções;

♦ O vocabulário forma o conjunto de instruções, quedetermina a interface hardware/software.

♦ Computadores com arquiteturas diferentesimplementam conjuntos de instruções distintos

Page 2: Oc2 cap03

Conjunto de Instruções

It is easy to see by formal-logical methods that there

exist certain [instruction sets] that are in abstract

adequate to control and cause the execution of any

sequence of operations ... The really decisive

considerations from the present point of view, in

selection an [instruction set], are more of a practical

nature: simplicity of the equipment demanded by the

[instruction set], and the clarity of its application to the

actually important problems together with the speed

of its handling of those problems.

Burks, Goldstine and von Neumann, 1947

Page 3: Oc2 cap03

Conjunto de Instruções

As linguagens de máquina são bastante parecidas

entre si. Aprendendo bem uma é fácil aprender outra.

Isto ocorre porque:♦ Todas são baseadas nos mesmos princípios (arquitetura de von

Neumann);

♦ Existe um conjunto de operações básicas que todas as máquinas

devem fornecer;

♦ Projetistas têm um mesmo objetivo: encontrar uma linguagem que

torne fácil a construção do hardware e de compiladores,maximizando a performance e minimizando os custos →SIMPLICIDADE

Page 4: Oc2 cap03

Implementação de Programas

♦ Um Programa de Computador é, basicamente, umaseqüência de comandos ou instruções representando umalgoritmo a ser executado pela máquina.

♦ Normalmente os programadores usam Linguagens deProgramação de Alto Nível (LAN), como Pascal e C

♦ Entretanto, estas linguagens correspondem a um nível deabstração elevado.

♦ As linguagens dos processadores como o x86 ou o MIPScorrespondem a um nível de abstração baixo, e sãodenominadas de Linguagens de Baixo Nível (LBN)

♦ Desta maneira é necessário um processo de Tradução

Page 5: Oc2 cap03

Tradução

♦ As linguagens LBNs são definidas por uma série deMnemônicos, que são, basicamente, símbolos querepresentam código binários

♦ Por exemplo, no caso do MIPS a instrução de adiçãoé representada por add a, b, c• esta instrução determina que o processador some o

conteúdo de dois registradores (b, c) e coloque o resultadoem outro registrador (a)

♦ A instrução ADD segue um formato bem definido:• código correspondente ao mnemônico da instrução add• identificação do registrador destino• identificação do primeiro operando• identificação do segundo operando

Page 6: Oc2 cap03

Assembler x Linguagem de Máquina

♦ Entretanto, para que um programa seja entendidopela máquina, é necessário que suas instruçõesestejam codificadas na forma binária, isto é, na formade 0s e 1s.

♦ No MIPS, a instrução add corresponde ao códigobinário 000000100000

♦ O conjunto de instruções de uma arquitetura (naforma de Mnemônicos) corresponde à Linguagem deMontagem da arquitetura (Linguagem ASSEMBLY)

♦ O conjunto de instruções de uma arquitetura (naforma binária) corresponde à Linguagem de Máquina

Page 7: Oc2 cap03

Níveis de Abstração

♦ Diferentes Níveis de Abstração

Page 8: Oc2 cap03

Tradutores

♦ Tanto os programas implementados em LANs comoem LBN precisam ser traduzidos para a linguagemde máquina do processador

♦ O processo de tradução de uma linguagem de altonível (LAN) para linguagem de máquina é feitocompiladores ou interpretadores

♦ O processo de tradução de uma linguagem deMontagem para linguagem de máquina é feito portradutores denominados de Montadores (ouAssemblers).

Page 9: Oc2 cap03

Compiladores e Interpretadores

♦ Compiladores são tradutores que após várias fases(análise léxica, análise sintática, análise semântica,geração de código intermediário, otimização decódigo e geração de código de montagem) geramum programa executável.

♦ Na verdade, este programa executável deverá sercarregado em memória para ser executado. Quemfaz esta tarefa é um programa do sistemaoperacional (programa carregador ou loader)

♦ Interpretadores não geram código executável

♦ Os interpretadores traduzem cada instrução doprograma (em LAN ou Assembly) e a executam

Page 10: Oc2 cap03

Tradutores

♦ Montadores, Compiladores e Interpretadores:

montador

execução

Código fonte

(ling.Montagem)

CódigoObjeto

compilador

Códigofonte(LAN)

CódigoObjeto

execução

Interpretador

Códigofonte

(LAN ouAssembl

y)

execução

Page 11: Oc2 cap03

Conjunto de Instruções

O conjunto de instruções que veremos vemdo MIPS, utilizado por diversas empresas(NEC, Nintendo, Silicon Graphics, Sony, …)

Utilizaremos um simulador de MIPS chamadoSPIM, que tem versões para Unix, Windowse DOS. O SPIM pode ser baixado a partir daURL:

http://www.mkp.com/cod2e.htm

Page 12: Oc2 cap03

ISA do MIPS (simplificada)

♦ Categorias de Instruções:• Load/Store• Computação• Jump e Desvio• Ponto Flutuante• Gerenciamento de Memória• Especial

♦ 3 Formatos de Instrução: 32 bits

R0 - R31

PC

HI

LO

OP

OP

OP

rs rt rd sa funct

rs rt imediato

Destino do jump

Registradores

Page 13: Oc2 cap03

add a, b, c # a = b + cadd a, a, d # a = b + c + dadd a, a, e # a = b + c + d +e

Operações do Hardware

Todo computador deve ser capaz de realizaroperações aritméticas.

Instruções aritméticas no MIPS têm formato fixo,realizando somente uma operação e tendo três“variáveis”

Somente umainstrução porlinha

Comentários

ex: a = b + c + d + e

ex..: add a,b,c a = b+ c

Page 14: Oc2 cap03

Operações do Hardware

♦ Exigir que toda instrução tenha exatamentetrês operandos condiz com a filosofia demanter o hardware simples: hardware paranúmero variável de parâmetros é maiscomplexo que para número fixo.

Princípio #1 para projetos: Simplicidadefavorece a regularidade

Page 15: Oc2 cap03

Exemplo

♦ Qual o código gerado por um compilador Cpara o seguinte trecho?

add a, b, c #a = b + csub d, a, e #d = a - e

a = b + c;d = a – e;

Page 16: Oc2 cap03

Exemplo 2

♦ Qual o código gerado por um compilador Cpara o seguinte trecho?

add t0, g, h # temporário t0 = g+ hadd t1, i, j # temporário t1 = i +jsub f, t0, t1 #f = (g + h) – (I + j)

Somente uma operação é feita por instrução: necessidade de variáveis temporárias.

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

Page 17: Oc2 cap03

Operandos e Registradores

♦ Ao contrário das linguagens de alto nível,operandos de instruções aritméticas não podemser quaisquer variáveis

→ são escolhidos dentre um conjunto deregistradores:

→ Número limitado de endereços especiais construídosdiretamente no hardware;

→ Blocos básicos para construção de computadores, poissão primitivas usadas em projeto de hardware quetambém são vistas pelo programador;

Page 18: Oc2 cap03

Registradores : benefícios

♦ Registradores no hardware, dentro doprocessador → mais rápidos que memória

♦ Registradores são de mais fácil utilização porcompiladores:

♦ como um local para armazenamento temporário

♦ podem armazenar variáveis para reduzir o tráfegode memória e melhorar a densidade de código (umavez que os registradores podem ser especificadoscom menos bits que um endereço de memória)

Page 19: Oc2 cap03

Operandos e Registradores

♦ Registradores do MIPS são de 32 bits;♦ no MIPS, blocos de 32 bits são chamados de

palavra;♦ Número de registradores é limitado: MIPS → 32

registradores, numerados de 0 a 31

♦ Princípio #2 para projetos: menor é mais rápido

♦ Um número muito grande de registradoresaumentaria o período de clock.

Page 20: Oc2 cap03

Operandos e Registradores

♦ Apesar de podermos nos referir aosregistradores através de números, em MIPSexiste uma convenção de se utilizar nomes naforma $xy

♦ Usaremos:

♦ $s0, $s1, $s2, … para registradores quecorrespondam a variáveis em C

♦ $t0, $t1, $t2, … para registradores temporáriosnecessários para compilar o programa eminstruções MIPS

Page 21: Oc2 cap03

Exemplo

Qual o código gerado por um compilador Cpara o seguinte trecho?

add $t0, $s1, $s2 # temporário t0 = g+ hadd $t1, $s3, $s4 # temporário t1 = i +jsub $s0, $t0, $t1 # f = (g + h) – (I + j)

As variáveis f, g, h, i, j podem ser mapeadas nosregistradores $s0, $s1, $s2, $s3 e $s4, respectivamente.

f = (g + h) – (i + j)

Page 22: Oc2 cap03

Operandos e Registradores

♦ Estruturas de dados podem ser bastante complexas,com um número de elementos grande demais paraserem armazenados nos registradores♦ Estruturas de dados, como vetores, são armazenadas na

memória

♦ Operações aritméticas em MIPS só podem ser feitasquando os operandos estão em registradores

♦ MIPS deve fornecer instruções para transferir dados entrea memória e os registradores

♦ Para acessar uma palavra na memória, a instrução devefornecer um endereço de memória

Page 23: Oc2 cap03

Memória

♦ Memória é somente um grande vetorunidimensional, com o endereço atuando comoíndice no vetor, começando em 0.

3210

100101011

Processador

DadosEndereços

Memória

Page 24: Oc2 cap03

Transferindo dados damemória

♦ A instrução de transferência de dados da memóriapara o registrador é chamada de load.

♦ Formato:

♦ Endereço de memória acessado é dado pela somada constante (chamada de offset) com o conteúdodo registrador base

Em MIPS, o nome da instrução é:lw (load word)

lw registrador destino, constante (registradorbase)

Page 25: Oc2 cap03

Exemplo♦ Suponha que temos um apontador a para um inteiro que está na

memória, com o endereço de memória dado no registrador $s3(ou seja, o apontador a está em $s3). Suponha ainda que ocompilador associou as variáveis g e h aos registradores $s1 e$s2. Qual o código para o seguinte trecho em C?

♦ Primeiro temos que pegar o operando que está na memória etransferi-lo para um registrador:

g = h + *a;

lw $t0, 0($s3) # temporário t0 =*aadd $s1, $s2, $t0 # g = h + *a

Page 26: Oc2 cap03

Vetor A = [0,0,0,0,15], com 5 posições, começando noendereço de memória 102. Este endereço é chamado deendereço base do vetor. Assim, 102 é o endereço de A[0],103o de A[1], ...,106 o de A[4].

Vetor na memória

Dados

Endereços

Endereço basede A

... 5 10 0 0 0 0 15 42 ...

... 100 101 102 103 104 105 106 107 ...

Page 27: Oc2 cap03

Exemplo

♦ Suponha que o vetor A tenha 100 posições, e que ocompilador associou as variáveis g e h aos registradores$s1 e $s2. Temos ainda que o endereço base do vetor A édado em $s3. Qual o código para

♦ Primeiro temos que pegar o operando que está namemória e transferi-lo para um registrador:

g = h + A[8]?

lw $t0, 8($s3) # temporário t0 =A[8]add $s1, $s2, $t0 # g = h + A[8]

Page 28: Oc2 cap03

10010

1011

Acesso à memória♦ Uma vez que bytes (8 bits) são úteis em muitos

programas, a maior parte das arquiteturas permite acessarbytes;

♦ Portanto, o endereço de uma palavra é o endereço de umdos 4 bytes dentro da palavra

♦ Assim, endereços de palavras consecutivas diferem em 4

12840

ProcessadorDadosEndereços

Memória

Page 29: Oc2 cap03

Cada posição do vetor (de inteiros) é uma palavra, e portantoocupa 4 bytes

Vetor A = [0,0,0,0,15], com 5 posições, começando noendereço de memória 408. Assim, 408 é o endereço deA[0],412 o de A[1], 416 o de A[2], 420 o de A[3] e 424 o deA[4].

Vetor na memória (2)

Dados

Endereços

Endereço basede A

... 5 10 0 0 0 0 15 4 2 ... ... 400 404 408 412 416 420 424 428 ...

Page 30: Oc2 cap03

Exemplo♦ Suponha que o vetor A tenha 100 posições, e que o

compilador associou a variável h ao registrador $s2.Temos ainda que o endereço base do vetor A é dado em$s3. Qual o código para:

♦ A nona posição do vetor A, A[8], está no offset 8 x 4 = 32

♦ A décima-terceira posição do vetor A, A[12], está no offset12 x 4 = 48

A[12] = h + A[8] ?

lw $t0, 32($s3) # temporário t0 = A[8]add $t0, $s2, $t0 # temporário t0 = h + A[8]

lw $t0, 48($s3) # carrega A[12] em $t0!!!!

Page 31: Oc2 cap03

Transferindo dados para amemória

♦ A instrução de transferência de dados de um registradorpara a memória é chamada de store.

♦ Formato:

♦ Endereço de memória acessado é dado pela soma daconstante (chamada de offset) com o conteúdo doregistrador base

No MIPS, o nome da instrução é: sw (store word)

sw registrador fonte, constante (registradorbase)

Page 32: Oc2 cap03

Endereço absoluto de A[3]

♦ Para obter o endereço absoluto precisamos:

0 1 2 3 4 5 6 7 8 9...

Registrador baseexe. $s2

Variável i ( i = 3) ($s4)

deslocamento(offset)offset = 4*i

endereço = $s2 + 4*3

Page 33: Oc2 cap03

Exemplo: variável de índice

♦ Suponha que o vetor A tenha 100 posições, e que ocompilador associou as variáveis g, h e i aos registradores$s1, $s2 e $s4. Temos ainda que o endereço base dovetor A é dado em $s3. Qual o código para:

♦ Precisamos primeiro calcular o endereço de A[i]. Antes desomar i ao endereço base de A, devemos multiplicar i por4. Vamos fazer isto por enquanto da seguinte forma:

g = h + A[i] ?

add $t1, $s4, $s4 # $t1 = 2 * iadd $t1, $t1, $t1 # $t1 = 4 * i

Page 34: Oc2 cap03

Variável de índice

♦ Para pegarmos A[i], somamos $t1 com o endereço basede A, dado em $s3:

♦ Agora podemos carregar A[i] para um registradortemporário, e realizar a soma, que será armazenada em g:

add $t1, $t1, $s3 # $t1 = endereço deA[i]

lw $t0, 0($t1) # temporário $t0 = A[i]add $s1, $s2, $t0 # g = h + A[i]

Page 35: Oc2 cap03

Resumo da Tradução

g = h + A[i]

add $t1, $s4, $s4 # $t1 = 2 * iadd $t1, $t1, $t1 # $t1 = 4 * iadd $t1, $t1, $s3 # $t1 = endereço de A[i]lw $t0, 0($t1) # temporário $t0 = A[i]add $s1, $s2, $t0 # g = h + A[i]

Page 36: Oc2 cap03

Exercício

Temos ainda que o endereço base do vetor A édado em $s2, e que as variáveis i e g são dadasem $s0 e $s1, respectivamente. Qual o códigopara

A[i+g] = g + A[i] – A[0]?

Page 37: Oc2 cap03

Solução

add $t0, $s0, $s0 # $t0 = 2*iadd $t0, $t0, $t0 # $t0 = 4*iadd $t0, $t0, $s2 # $t0 = endereço de A[i]lw $t1, 0($t0) # $t1 = A[i]add $t1, $s1, $t1 # $t1 = g + A[i]lw $t0, 0($s2) # $t0 = A[0]sub $t1, $t1, $t0 # $t1 = g + A[i] – A[0]add $t0, $s0, $s1 # $t0 = i + gadd $t0, $t0, $t0 # $t0 = 2 * (i + g)add $t0, $t0, $t0 # $t0 = 4 * (i + g)add $t0, $t0, $s2 # $t0 = endereço de A[i + g]sw $t1, 0($t0) # A[i + g] = g + A[i] – A[0]

A[i+g] = g + A[i] – A[0]?i,g,A = $s0, $s1,$s2

Page 38: Oc2 cap03

Utilizando os registradores

♦ Muitos programas têm mais variáveis do que onúmero de registradores presente na máquina.

♦ Compilador tenta manter as variáveis mais usadasnos registradores e coloca o resto na memória,utilizando loads e stores para mover os dadosentre a memória e os registradores:

♦ Compiladores têm que utilizar os registradores deforma eficiente.

Page 39: Oc2 cap03

♦ MIPS requer que todas as palavras comecem emendereços que são múltiplos de 4 bytes

♦ Chamamos isto de alinhamento: objetos têm que terendereços que sejam múltiplos de seus tamanhos.

0 1 2 3

Alinhado

Não alinhado

Alinhamento de Dados naMemória

Page 40: Oc2 cap03

♦ Processadores podem numerar bytes dentro de umapalavra, de tal forma que o byte com o menornúmero é o mais a esquerda ou o mais a direita. Istoé chamado de byte order.

♦ Ex: .byte 0, 1, 2, 3

♦ Big endian: IBM 360/370, Motorola 68k, MIPS, Sparc, HPPA

♦ Little Endian: Intel 80x86, MIPS, DEC Vax, DEC Alpha

3 2 1 0little endian

0 1 2 3bigendian

Ordenamento dos Bytes

Page 41: Oc2 cap03

Representando Instruções noComputador

♦ Números são armazenados no hardware na base2, ou binária.

♦ Instruções podem ser representadas comonúmeros; na verdade, cada pedaço da instrução éum número, e o posicionamento lado a ladodestes números é que formam a instrução.

♦ Existe uma convenção em MIPS para associarnomes de registradores a seus números:

$s0, $s1, …, $s7 → 16, 17, …,23$t0, $t1, …, $t7 → 8, 9, …, 15

Page 42: Oc2 cap03

Representando Instruções noComputador ...

♦ Linguagem de máquina para a instrução

♦ Cada um destes segmentos é chamado de campo. Oprimeiro e o último campos, juntos, dizem que a instruçãoé uma adição. O segundo diz qual é o primeiro registradorfonte (17 = $s1) e o terceiro o segundo registrador fonte(18 = $s2). O quarto campo é o registrador destino (8 =$t0). O quinto campo não é usado nesta instrução, e poristo tem valor zero.

0 17 18 8 0 32

add $t0, $s1, $s2

Page 43: Oc2 cap03

♦ Também podemos representar tais números em binário:

♦ Para distinguir da linguagem Assembly, chamamos estarepresentação numérica de linguagem de máquina, e aseqüência de tais instruções de código de máquina

♦ Chamamos esta estrutura de campos de formato dainstrução. Todas as instruções em MIPS possuem 32 bits(“simplicidade favorece regularidade”).

000000 10001 10010 01000 00000100000

Representando Instruções noComputador ...

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

Page 44: Oc2 cap03

Formato Instrução MIPS

♦ Daremos nomes aos campos para simplificar a discussão:

♦ op: operação básica da instrução (opcode);♦ rs: primeiro registrador fonte;♦ rt: segundo registrador fonte;♦ rd: registrador destino, recebe o resultado da operação♦ shamt: quantidade de shift (veremos no capítulo 4)♦ funct: função; seleciona a variante específica da operação

dada no campo op, também chamada de código de função

op rs rt rd shamtfunct 6 bits 5 bits 5 bits 5 bits 5 bits 6

bits

Page 45: Oc2 cap03

Formato Instrução MIPS...

♦ Um problema acontece quando uma instrução necessitade campos mais longos que os mostrados neste exemplo.

♦ Ex.: a instrução lw precisa especificar dois registradores euma constante. Se a constante for ser representada nocampo de um dos registradores, o valor dela ficará limitadoa 32 (2^5). Obviamente, este valor é pequeno demaispara ser útil.

♦ Assim, temos um conflito entre o desejo de que todas asinstruções tenham o mesmo tamanho e o desejo de quetenhamos um único formato de instruções.

Page 46: Oc2 cap03

Formato Instrução MIPS...

♦ Princípio #3 para projetos: bons projetosdemandam bons compromissos.

♦ Compromisso escolhido pelos projetistas do MIPS: mantertodas as instruções com o mesmo tamanho → diferentestipos de instrução podem ter diferentes formatos deinstrução.

♦ O formato mostrado anteriormente é chamado de tipo-R

(de registrador) ou formato-R

♦ Um segundo formato é usado pelas instruções de

transferência de dados: tipo-I ou formato-I

Page 47: Oc2 cap03

Formato Instrução MIPS...

♦ Formato tipo-I:

♦ O endereço de 16 bits significa que uma instrução lw podecarregar qualquer palavra dentro de uma região de ±2^15ou 32768 bytes (2^13 ou 8192 palavras) em relação aoendereço no registrador base rs.

op rs rt endereço

6 bits 5 bits 5 bits 16 bits

Page 48: Oc2 cap03

Formato Instrução MIPS...

♦ Ex: lw $t0, 32($s3) #temporário $t0 = A[8]

♦ Neste exemplo, rs recebe 19 ($s3), rt recebe 8 ($t0) e ocampo endereço recebe o valor 32. Op neste caso é 35(lw). Em uma instrução de load, o campo rt determina oregistrador destino!!

♦ Apesar do hardware ficar mais complexo ao utilizarmosdiferentes formatos de instrução, podemos reduzir esteaumento de complexidade ao mantermos certasimilaridade entre os formatos (ex.: 3 primeiros camposnos formatos tipo-R e tipo-I são os mesmos; comprimentodo último campo tipo-I é igual à soma dos 3 últimos tipo-R).

op rs rt endereço

Page 49: Oc2 cap03

Formato Instrução MIPS...

♦ Primeiro campo determina tipo do formato.

♦ Pergunta: por que não utilizar somente um campode 12 bits para os campos op e funct nasinstruções de tipo-R??

Page 50: Oc2 cap03

Codificação das InstruçõesVistas

Instrução

Formato op rs rt rd shamt funct

endereço

add R 0 reg reg reg 0 32 não

sub R 0 reg reg reg 0 34 não

lw I 35 reg reg não

não não ender.

sw I 43 reg reg não

não não ender.

$s0, $s1, …, $s7 → 16, 17, …, 23$t0, $t1, …, $t7 → 8, 9, …, 15

Page 51: Oc2 cap03

Exemplo de compilaçãomanual

♦ Suponha que $t1 tenha o endereço base de A e que $s2corresponda a h, traduza a seguinte linha em C paracódigo de máquina MIPS: A[300] = h + A[300];

♦ Primeiro, temos que o código em assemblycorrespondente é:

♦ Qual o código de máquina destas 3 instruções?

lw $t0,1200($t1) # $t0 = A[300]add $t0, $s2, $t0 # $t0 = h + A[300]sw $t0, 1200($t1) # A[300] = h +A[300]

Page 52: Oc2 cap03

Exemplo de compilação manual...

lw $t0,1200($t1)add $t0, $s2, $t0sw $t0, 1200($t1)

op rs rt

rd

Endereço /shamt

funct

35 9 8 1200

0 18

8 8 0 32

43 9 8 1200

op rs rt rd Endereço /shamt

funct

100011 01001 01000 0000 0100 1011 0000

000000 10010 01000 01000 00000 100000

101011 01001 01000 0000 0100 1011 0000

Page 53: Oc2 cap03

Idéia geral: conceito de programaarmazenado

♦ Computadores de hoje são construídos baseados em doisprincípios fundamentais:

• Instruções podem ser representadas como números

• Programas podem ser armazenados na memória paraserem lidos ou escritos da mesma forma que números

♦ Conceito de programa armazenado, fundamental para aComputação!!!

Page 54: Oc2 cap03

Instruções para tomada dedecisões

♦ O que distingue um computador de uma calculadorasimples é a habilidade de tomar decisões.

♦ Com base na entrada e nos resultados computados,diferentes instruções são executadas.

♦ Em linguagens de alto nível, uma das formas de se tomardecisões é através das instruções if e goto.

♦ Em MIPS, temos duas instruções que atuam de maneirasimilar a instruções que combinam if com goto:

• beq registr1, registr2, L1 # branch if equal• bne registr1, registr2, L1 # branch if not equal

rótulo (label)

Page 55: Oc2 cap03

Instruções de decisão no MIPS

♦ em C, isto seria equivalente a:

beq registr1, registr2,L1

Semântica: “Desvie se (valores nos registradores são) iguais”

if (registr1== registr2) gotoL1

Page 56: Oc2 cap03

Instruções de decisão no MIPS ...

♦ em C, isto seria equivalente a:

♦ Estas instruções são chamadas de desvios condicionais.

bne registr1, registr2, L1

Semântica: “desvie se (valores nos registradores) nãosão iguais”

if (registr1!=registr2) goto L1

Page 57: Oc2 cap03

Exemplo

♦ Se as variáveis f, g, h, i, j correspondem aos registradores$s0 a $s4, qual é o código compilado para o seguintetrecho em C?

Como instruções são armazenadas na memória, elas têmendereços também!!

if (i == j) goto L1; f = g + h;L1: f = f – i;

beq $s3, $s4, L1 # vá para L1 se $s3 ==$s4 add $s0, $s1, $s2 # f = g + h (se i != j)

L1: sub $s0, $s0, $s3 # f = f – i (se i == j)

Page 58: Oc2 cap03

Instruções para tomada dedecisões

♦ O montador (assembler) faz com que o compilador ou oprogramador em linguagem assembly não tenha que ficarcalculando endereços para os desvios (branches) aopermitir o uso de rótulos.

♦ Compiladores criam desvios e rótulos sem que oprogramador de linguagens de alto nível os tenha queespecificar. Esta é uma das razões de por que é maisrápido programar em linguagens de alto nível.

Page 59: Oc2 cap03

Desvio incondicional em MIPS

♦ MIPS tem um desvio incondicional:

♦ Chamada de instrução de salto (jump): salte para o rótuloespecificado, incondicionalmente

♦ Em C, isto seria equivalente a: goto label

♦ Podemos pensar que isto é equivalente a:

• Uma vez que a condição sempre é satisfeita

♦ Existe um formato de instrução para desvio (tipo-J ou formato-J), como veremos mais à frente.

j rotulo

beq $0,$0,rotulo

Page 60: Oc2 cap03

Exemplo: código para if

♦ Se as variáveis f, g, h, i, j correspondem aos registradores$s0 a $s4, qual é o código compilado para o seguintetrecho em C?

♦ Queremos implementar o seguinte fluxo:

Fim

i == j?

f=g+h f=g-h

(falso) i != j

(verdadeiro) i == j

if (i == j) f = g + h; else f = g – h;

Page 61: Oc2 cap03

Exemplo: código para if

Primeiro devemos saber se i é igual a j:

Se i == j, somamos g com h e armazenamos em f

Precisamos agora ir para o fim do if. Para istoutilizamos um desvio incondicional ( j, de jump ):

Tratamos agora o caso em que i != j

bne $s3, $s4, else # vá para else se i !=j

add $s0, $s1, $s2 # f = g + h (se i ==j)

j Fim # vá para Fim

Else: sub $s0, $s1, $s2 # f = g – h (se i!= j)Fim:

Page 62: Oc2 cap03

Loops

♦ Decisões são importantes para escolher entre duasalternativas, e para iterar uma computação (loop).Usamos as mesmas instruções assembly para as duassituações.

♦ Tudo depende de onde colocamos o rótulo para o qualsaltaremos.

Page 63: Oc2 cap03

Exemplo de loop♦ Se as variáveis g, h, i, j correspondem aos registradores $s1 a $s4, e

o endereço base do vetor A (de 100 elementos) está em $s5, compileo seguinte trecho em C.

Loop: g = g + A[i];if ( (i = i + j) != h ) goto Loop;

Loop: add $t1, $s3, $s3 # $t1 = 2 * iadd $t1, $t1, $t1 # $t1 = 4 * iadd $t1, $t1, $s5 # $t1 = ender. de

A[i]lw $t0, 0($t1) # $t0 = A[i]add $s1, $s1, $t0 # g = g + A[i]add $s3, $s3, $s4 # i = i + jbne $s3, $s2, Loop # Loop se (i != h)

Page 64: Oc2 cap03

Compilando um laço do tipo while

♦ Programadores normalmente não utilizam comandos goto(o uso deles não é considerado boa prática deprogramação!!!). Assim, o compilador tem que traduzir osloops tradicionais em linguagem MIPS.

♦ Exemplo em C:

♦ Se i, j, e k correspondem aos registradores $s3, $s4 e$s5, e o endereço base do vetor save está no registrador$s6, qual o código assembly MIPS correspondente?

while (save[j] == k)i = i + j;

Page 65: Oc2 cap03

♦ Temos inicialmente que carregar save[i] para umregistrador temporário:

♦ Agora fazemos o teste do loop, saindo se save[i] != k

♦ Devemos agora voltar para o while no inicio do loop

Loop: add $t1, $s3, $s3 # $t1 = 2 * iadd $t1, $t1, $t1 # $t1 = 4 * iadd $t1, $t1, $s6 # $t1 = endereço de save[i]lw $t0, 0($t1) # $t0 = save[i]

bne $t0, $s5, Fim # vá para Fim se save[i] != kadd $s3, $s3, $s4 # i = i + j

j Loop # vá para LoopFim:

Compilando um laço do tipo while

Page 66: Oc2 cap03

Comparando doisregistradores

♦ Os testes de igualdade ou desigualdade sãoprovavelmente os mais populares, mas às vezesqueremos testar se uma variável é menor do que outra

♦ Por exemplo, um for pode querer testar se um índice émenor do que zero.

♦ Em MIPS, temos uma instrução que compara os valoresde dois registradores, e atribui 1 a um terceiro registradorse o primeiro registrador é menor que o segundo, e 0caso contrário:

♦ → Se $s3 < $s4, $t0 recebe 1, caso contrário, recebe 0

slt (set on less than) slt $t0, $s3, $s4

Page 67: Oc2 cap03

Compilando um laço do tipo while

♦ Compiladores MIPS utilizam as instruções slt, beq, bne, eo valor fixo zero para criar todas as relações decomparação: igual, diferente, menor que, menor ou iguala, maior que e maior ou igual a.

♦ O registrador $zero (registrador 0) tem seu valor fixadoem zero.

Page 68: Oc2 cap03

Exemplo: desvio se menor que

♦ Qual o código para testar se a variável a, mapeada noregistrador $s0, é menor que a variável b (registrador $s1), edesviar para o rótulo Menor se a condição for satisfeita?

♦ Primeiro usamos a instrução slt e um registrador temporário:

♦ Registrador $t0 é 1 se a < b. Portanto, testamos se $t0 não é 0:

slt $t0, $s0, $s1 # $t0 = (a <b)?

bne $t0, zero, Menor # vá para Menor se $t0!=0# ou seja, se (a < b)

Page 69: Oc2 cap03

Tradução de if (a < b) then... else

if (i < j) f = g + h;

else f = g – h;

slt $t0, $s0, $s1 # $t0 = (a < b)?

beq $t0, zero, Else # vá para else se a>= b

add $s0, $s1, $s2 # f = g + h (se i == j)

j Fim # vá para FimElse: sub $s0, $s1, $s2 # f = g – h (se i != j)Fim:

Page 70: Oc2 cap03

Por que não utilizar uma instruçãosó para “desvie se menor que”?

♦ MIPS não tem instruções como “desvie se menor que”porque elas são complicadas demais: ou elasaumentariam o período de clock ou seriam necessáriosmais ciclos de clock por instrução (além de fazer com quefosse necessário mais hardware).

♦ As duas instruções slt e bne são mais rápidas e maisúteis, pois também servem para outros propósitos.

Page 71: Oc2 cap03

Um outro tipo de desvioincondicional

♦ Até agora vimos uma instrução de desvio incondicional,através da instrução

♦ Nesta instrução, temos que especificar um rótulo, ou sejaum endereço fixo, para o qual o Program Counter serádesviado.

♦ Em diversas situações, pode ser interessante quedesviemos para um endereço variável, armazenado emum registrador. Para tanto, existe a instrução jr:

j Rotulo # desvio para rótulo

jr registrador #desvio para endereço #contido no

registrador

Page 72: Oc2 cap03

Comando switch

♦ A linguagem C define o comando switch, que permiteque o programador selecione uma alternativa dentrevárias, dependendo de um único valor.

♦ Como compilar o seguinte trecho de código?

switch (k) { case 0: f = i + j; break; case 1: f = g + h; break; case 2: f = g – h; break; case 3: f = i – j; break;

}

Page 73: Oc2 cap03

Comando switch

♦ Uma forma de se fazer isto é tratar o comando switchcomo sendo uma seqüência de comandos if:

if ( (k >= 0) && (k <= 3))if (k == 0) f = i + j;else if (k == 1) f = g + h;else if (k == 2) f = g - h;else f = i + j;

Page 74: Oc2 cap03

Comando switch

♦ Desta forma, se temos n casos possíveis, teremos, emmédia, que testar n/2 casos contra k para encontrar ocaso desejado.

♦ Como podemos implementar o comando switch demaneira mais eficiente?

♦ Em alguns casos, podemos utilizar uma tabela deendereços, de tal forma que ao acessar a tabela naposição correspondente a k, TabEnd[k], obtenhamos oendereço do rótulo desejado.

♦ Desta maneira, podemos tomar a decisão em tempoconstante.

Page 75: Oc2 cap03

Comando switch

♦ Melhorando o comando switch:

♦ Vamos supor que as variáveis f, g, h, i, j, k estão nosregistradores $s0 a $s5, e que $t2 contenha o valor 4.

switch (k) {case 0: f = i + j; break;case 1: f = g + h; break;case 2: f = g – h; break;case 3: f = i – j; break;

}

Page 76: Oc2 cap03

Comando switch

♦ Utilizaremos a variável k como índice na tabela deendereços, e desviar de acordo com o valor carregado;

♦ Primeiro, temos que verificar se 0 <= k <= 3:

♦ Vamos utilizar k para indexação; por isto temos quemultiplicar k por 4.

slt $t3, $s5, $zero # teste se k<0bne $t0, $zero, Fim # se k<0, vá para Fimslt $t3, $s5, $t2 # teste se k<4beq $t3, $zero, Fim # se k>=4 vá para Fim

Page 77: Oc2 cap03

Comando switch

♦ Suponha que o vetor de endereços TabEnd, cujoendereço está em $t4, possui quatro posições, com osendereços correspondentes aos rótulos L0, L1, L2 e L3:

♦ Agora saltamos para o endereço presente em $t0:

add $t1, $s5, $s5 # t1 = 2 * kadd $t1, $t1, $t1 # t1 = 4 * k

add $t1, $t1, $t4 # t1 = endereço deTabEnd[k]lw $t0, 0($t1) # t0 = TabEnd[k]

jr $t0

Page 78: Oc2 cap03

Comando switch

♦ Por fim tratamos os casos do switch:

L0: add $s0, $s3, $s4 # f = i+jj Fim

L1: add $s0, $s1, $s2 # f = g + hj Fim

L2: sub $s0, $s1, $s2 # f = g – hj Fim

L3: sub $s0, $s3, $s4 # f = i – j (não precisamos saltar# para o Fim, já que a próxima# instrução tem o rótulo Fim)

Fim:

Page 79: Oc2 cap03

Resumo: instruções vistas atéagora

Categoria Instrução Exemplo SemânticaAdição add $s1, $s2, $s3 $s1 = $s2 + $s3AritméticaSubtração sub $s1, $s2, $s3 $s1 = $s2 - $s3Load word lw $s1, 100($s2) $s1 = Mem[$s2 + 100]Transferência

de dados Store word sw $s1, 100($s2) Mem[$s2 + 100] = $s1Branch onequal

beq $s1, $s2, L If ($s1 == $s2) goto L

Branch on notequal

bne $s1, $s2, L If ($s1 != $s2) goto L

DesvioCondicional

Set on lessthan

slt $s1, $s2, $s3 if ($s2 < $s3) $s1 = 1; else $s1 = 0;

Jump j 2500 goto 10000DesvioIncondicional Jump register jr $t1 goto $t1

Page 80: Oc2 cap03

Instruções de suporte aprocedimentos

♦ Procedimentos ou subrotinas são utilizadas pelosprogramadores para:• Facilitar a compreensão e manutenção de código;• Possibilitar o reaproveitamento de código.

♦ O código de um procedimento fica “isolado”, sendo ainterface com o restante do código dada pelosargumentos de entrada e pelos resultados de saída.

Page 81: Oc2 cap03

Instruções de suporte aprocedimentos

♦ Na execução de um procedimento, um programa deveseguir os seguintes passos:• Colocar os argumentos (parâmetros) em um lugar em

que o procedimento possa acessá-los;• Transferir o controle para o procedimento;• Executar a tarefa desejada;• Colocar o resultado da execução em um lugar em que

o código que chamou o procedimento possa acessar;• Retornar o controle para o ponto de origem.

Page 82: Oc2 cap03

Instruções de suporte aprocedimentos

♦ Qual o lugar mais rápido que pode armazenar dados emum computador?

♦ Registrador. Queremos utilizar registradoressempre que possível

♦ Software para MIPS aloca os seguintes registradorespara chamada de procedimentos:

♦ $a0 - $a3: quatro registradores que são utilizados parapassar parâmetros para os procedimentos;

♦ $v0 - $v1: dois registradores que são utilizados pararetornar valores calculados pelos procedimentos(resultados)

♦ $ra: registrador utilizado para retornar para o ponto deorigem (ra = return address).

Page 83: Oc2 cap03

Valores de retorno do procedimento

Desvio para procedimento

Instruções de suporte aprocedimentos

Execução do procedimento

Preparo argumentos para o procedimento $a0-$a3

$ra;desvi

o

$v0-$v1

Continuação do programa

Retorno para a continuação do programa jr $ra

Page 84: Oc2 cap03

C

MIPS

Exemplo de procedimento

... soma(a,b);... /* a:$s0; b:$s1 */}

int soma(int x, int y) { /* x:$a0; y:$a1 */return x+y;

}

endereço1000 add $a0,$s0,$zero # x = a1004 add $a1,$s1,$zero # y = b1008 addi $ra,$zero,1016 # $ra = 10161012 j soma # desvio para soma1016 ...2000 soma: add $v0,$a0,$a12004 jr $ra # volte p/ origem,

# no endereço1016

Page 85: Oc2 cap03

jal (jump and link)

♦ O assembly MIPS tem uma instrução de desvio só paraprocedimentos; ela causa um desvio para um endereço,e ao mesmo tempo guarda o endereço da próximainstrução em $ra: jal (jump and link).

jal Rotulo #desvio para o procedimento que tem#endereço marcado por Rótulo

Page 86: Oc2 cap03

jal (jump and link) ...

♦ Link, neste caso, quer dizer que é formada, no registrador$ra, uma referência para a instrução que vem logo após ainstrução jal, ou seja, a instrução jal é equivalente aoseguinte código:

♦ Por que existe a instrução jal??Procedimentos são muito comuns:

“faça o caso comum ser rápido”

$ra = PC + 4j Rótulo

Page 87: Oc2 cap03

C

MIPS

Exemplo de procedimento(revisado)

... soma(a,b);... /* a:$s0; b:$s1 */}

int sum(int x, int y) { /* x:$a0; y:$a1 */return x+y;

}

end1000 add $a0,$s0,$zero # x = a1004 add $a1,$s1,$zero # y = b1008 jal soma # prepara $ra e

# jump p/ procsoma1012 ...2000 soma: add $v0,$a0,$a12004 jr $ra # volte p/ origem,

# no endereço 1012

Page 88: Oc2 cap03

Exercício

♦ Qual o código em assembly para MIPS equivalente aoseguinte trecho em C, estando i em $s0 e j em $s1?

• i = sub(i,j); /* sub(a, b) {return a-b;} */

...add $a0, $s0, $zero # a0 = iadd $a1, $s1, $zero # a1 = jjal sub # chama a função

subadd $s0, $v0, $zero # i = sub(i,j)...

sub: sub $v0, $a0, $a1 # $v0 = a – bjr $ra # retorne para

origem

Page 89: Oc2 cap03

Usando mais registradores

♦ Suponha que um procedimento necessite de maisregistradores do que os 4 registradores de argumentos eos 2 de retorno.

♦ O código que vai chamar este procedimento pode estarutilizando diversos registradores, de tal forma que oprocedimento não pode utilizar os registradores dequalquer forma, uma vez que valores importantespoderiam ser perdidos.

♦ Assim, qualquer registrador que o procedimento utilize eque possa ser do interesse do código “chamador” deve terseu valor restaurado para o valor anterior à execução doprocedimento.

Page 90: Oc2 cap03

Usando mais registradores

♦ Como fazer isto?

♦ Processo conhecido por register spilling:• Uso de uma pilha, estrutura de dados do tipo LIFO

(last-in first-out);• Temos um apontador para o topo da pilha;• Este apontador é ajustado em uma palavra para cada

registrador que é colocado na pilha (operaçãoconhecida por push), ou retirado da pilha (operaçãoconhecida por pop).

• Em MIPS, um registrador é utilizado somente paraindicar o topo da pilha: sp (stack pointer)

Page 91: Oc2 cap03

Usando mais registradores

♦ Por razões históricas, a pilha “cresce” do maior endereçopara o menor endereço:

♦ Para colocar um valor na pilha (push), devemosdecrementar $sp em uma palavra e mover o valordesejado para a posição de memória apontada por $sp;

♦ Para retirar um valor da pilha (pop), devemos ler estevalor da posição de memória apontado por $sp, e entãoincrementar $sp em uma palavra.

Page 92: Oc2 cap03

0

Endereço

Código Programa

Estático Variáveis declaradas umavez para todo programa

HeapEspaço explicitamente criadomalloc: apontadores em C

PilhaEspaço para procedimentosarmazenarem informações$sp

stackpointer

Alocação de memória em C

Page 93: Oc2 cap03

Exemplo: exemplo_proc

♦ Suponha que tenhamos o seguinte código:

Vamos gerar o código correspondente em assembly MIPS.

int exemplo_proc (int g, int j, int i, int h){

int f;f = (g+h) – (i+j);return f;

}

Page 94: Oc2 cap03

Exemplo : exemplo_proc

♦ Os argumentos g, h ,i e j correspondem aos registradores$a0, $a1, $a2 e $a3, e f corresponde a $s0. Primeirocolocamos o rótulo do procedimento:

♦ exemplo_proc:

♦ Devemos então armazenar os registradores que serãoutilizados pelo procedimento. Como estaremos utilizandoos registradores $t0, $t1 e $s0, vamos colocá-los na pilha:

subi $sp, $sp, 12 # cria espaço para mais 3 itens napilhasw $t1, 8(sp) # empilha $t1sw $t2, 4(sp) # empilha $t2sw $s0, 0(sp) # empilha $s0

Page 95: Oc2 cap03

Exemplo : exemplo_proc

Como ficou a pilha?

$sp

Valoresempilhados

antes dafunção

Pilha antesda função

$t1

$t0

$s0$sp

Valoresempilhados

antes dafunção

Pilha duranteexecução da função

Page 96: Oc2 cap03

Exemplo : exemplo_proc

♦ As próximas instruções correspondem ao corpo doprocedimento:

♦ O resultado deve ser armazenado no registrador $v0:

add $v0, $s0, $zero # retorna f em $v0

add $t0, $a0, $a1 # $t0 = g + hadd $t1, $a2, $a3 # $t1 = i + jsub $s0, $t0, $t1 # f = $t0 = (g+h) –(i+j)

Page 97: Oc2 cap03

Exemplo : exemplo_proc

♦ Antes de sair do procedimento, devemos restaurar osvalores de $t0, $t1 e $s0, retirando-os da pilha:

♦ Voltamos então para a instrução seguinte ao ponto emque a função exemplo_proc foi chamada:

lw $s0, 0($sp) # desempilha $s0lw $t0, 4($sp) # desempilha $t0lw $t1, 8 ($sp) # desempilha $t1addi $sp, $sp, 12 # remove 3 itens da pilha

jr $ra # retorna para a subrotina quechamou

# este procedimento

Page 98: Oc2 cap03

Instruções de suporte aprocedimentos

♦ No exemplo anterior, nós utilizamos registradorestemporários e assumimos que os valores deles deveriamser guardados e restaurados.

♦ Para evitar que registradores que não são utilizados sejamempilhados e desempilhados, MIPS oferece duas classesde registradores:• $t0-$t9: 10 registradores temporários que não são

preservados pela função que é chamada.• $s0-$s7: 8 registradores que têm seus valores

preservados no processo de chamada deprocedimento. Desta forma, se estes registradoresforem utilizados pelo procedimento, eles devem terseus valores empilhados no início do procedimento edesempilhados no final.

Page 99: Oc2 cap03

Instruções de suporte aprocedimentos

♦ Esta simples convenção faz com que percamos menostempo empilhando e desempilhando registradores

♦ No exemplo, teríamos que preservar somente o valor de$s0.

♦ O que fazer se temos um código que utiliza registradorestemporários e vai chamar uma função??

♦ Podem aparecer problemas quando fazemos funções quechamam outras funções (por exemplo, funçõesrecursivas)??

Page 100: Oc2 cap03

Procedimentos aninhados

♦ Suponha que o programa principal chama a função A como argumento 3, ao colocar 3 em $a0 e utilizar a instruçãojal A.

♦ Suponha ainda que a função A chama a função B comargumento 7, ao colocar 7 em $a0 e utilizar a instruçãojal B.

♦ Uma vez que A ainda não terminou de executar temos umconflito no uso do registrador $a0.

♦ Um problema também aparece para o registrador $ra, queagora contém o valor para retorno de B.

♦ Se não tomarmos cuidado, poderemos não ser capazesnem de voltarmos para o programa principal!!!

♦ Como resolver?

Page 101: Oc2 cap03

Procedimentos aninhados:convenção sobre registradores

♦ Uma solução é empilhar todos os registradores queprecisam ser preservados.

♦ Para isto, temos que estabelecer uma convenção entre asubrotina que chama a função e a subrotina chamada,para estabelecer quais registradores serão preservados, epor quem.

♦ Definições• Chamadora: função que faz a chamada, utilizando jal;• Chamada: função sendo chamada.

♦ Podemos pensar nestas convenções como sendo umcontrato entre a Chamadora e a Chamada;

Page 102: Oc2 cap03

Por que utilizar convenções parachamadas de procedimentos?

♦ Se tanto a sub-rotina Chamadora quanto a Chamadaobedecerem a convenção, temos os seguintesbenefícios:

♦ programadores podem escrever funções quefuncionam juntas;

♦ Funções que chamam outras funções – como asrecursivas – funcionam corretamente.

Atenção!! Chamadora ou chamada não representa umapropriedade da função, mas sim o papel que a função exerceem uma chamada de procedimento específica. Assim, umafunção pode exercer o papel de chamadora e de chamada, sóque em diferentes chamadas de procedimento.

Page 103: Oc2 cap03

Direitos da Chamadora e daChamada

♦ Direitos da Chamada:• Utilizar livremente os registradores v, a, e t;• Assumir que os argumentos são passados

corretamente.

♦ Registradores que devem ser preservados pelaChamadora:• Endereço de retorno $ra• Argumentos $a0, $a1, $a2, $a3• Valores de retorno $v0, $v1• Registradores temporários $t0 - $t9

Page 104: Oc2 cap03

♦ Direitos da Chamadora• Utilizar os registradores s, sem que eles sejam

alterados pela Chamada• Assumir que os valores de retorno e a pilha estão

corretos

♦ Registradores que devem ser preservados pelaChamada:• Registradores $s $s0 - $s7

Direitos da Chamadora e daChamada

Page 105: Oc2 cap03

Exemplo: soma_recursiva

♦ Suponha que tenhamos o seguinte código, que calcula asoma n + (n-1) + … + 2 + 1 de forma recursiva:

♦ Vamos gerar o código correspondente em assemblyMIPS.

int soma_recursiva (int n){

if (n < 1)return 0;

elsereturn n + soma_recursiva(n-

1)}

Page 106: Oc2 cap03

Exemplo: soma_recursiva

♦ O parâmetro n corresponde ao registrador $a0.♦ Devemos inicialmente colocar um rótulo para a função, e

salvar o endereço de retorno, armazenado em $ra, oparâmetro $a0:

♦ Na primeira vez que soma_recursiva é chamada, o valorde $ra que é armazenado corresponde a um endereçoque está na sub-rotina que chama esta função

Soma_recursiva:subi $sp, $sp, 8 # prepara a pilha para receber

2# valores

sw $ra, 4($sp) # empilha $rasw $a0, 0($sp) # empilha $a0

Page 107: Oc2 cap03

Exemplo: soma_recursiva

♦ Vamos agora compilar o corpo da função. Inicialmente,testamos se n < 1:

♦ Se n >=1, a função deve retornar o valor 0. Não podemosnos esquecer de restaurar a pilha.

♦ Por que não carregamos os valores de $a0 e $ra antes deajustar $sp??

slti $t0, $a0, 1 # testa se n < 1beq $t0, $zero, L1 # se n>=1, vá paraL1

add $v0, $zero, $zero # valor de retorno é 0add $sp, $sp, 8 # remove 2 itens da pilhajr $ra # retorne para depois dejal

Page 108: Oc2 cap03

Exemplo: soma_recursiva

♦ Se n >=1, decrementamos n e chamamos novamente afunção soma_recursiva com o novo valor de n.

♦ Quando a soma para (n-1) é calculada, o programa voltaa executar na próxima instrução. Restauramos oendereço de retorno e o argumento anteriores, eincrementamos o apontador de topo de pilha:

L1:subi $a0, $a0, 1 # argumento passa a ser (n-1)

jal soma_recursiva # calcula a soma para (n-1)

lw $a0, 0($sp) # restaura o valor de nlw $ra, 4($sp) # restaura o endereço de retornoaddi $sp, $sp, 8 # retira 2 itens da pilha.

Page 109: Oc2 cap03

Exemplo: soma_recursiva♦ Agora o registrador $v0 recebe a soma do argumento

antigo $a0 com o valor atual em $v0 (soma_recursivapara n-1):

♦ Por último, voltamos para a instrução seguinte à quechamou o procedimento:

add $v0, $a0, $v0 # retorne n +soma_recursiva(n-1)

jr $ra # retorne para o“chamador”

Page 110: Oc2 cap03

Variáveis automáticas eestáticas

♦ Variáveis automáticas são aquelas que são locais a umprocedimento, e que portanto só são acessíveis enquantoo procedimento está ativado.

♦ Quando uma função contém dados que são grandesdemais para serem colocados em registradores, eles sãocolocados na pilha. Exemplos são estruturas de dadoscomo registros (structs) ou vetores estáticos (que nãousam malloc para alocação).

♦ Já as variáveis estáticas são aquelas que estão ativasdurante toda a execução do programa. Em C, elas são asvariáveis globais e as variáveis marcadas como static.

Page 111: Oc2 cap03

Variáveis automáticas eestáticas

♦ A região da pilha onde são armazenados os registradoressalvos e as variáveis locais a um procedimento é chamadade registro de ativação.

♦ Para facilitar o acesso a estas variáveis, o registrador $fp(frame pointer) é utilizado. Ele marca o início do registro deativação, e não é atualizado de forma automática, sósendo utilizado se houver variáveis do procedimento napilha. A vantagem de se usar $fp é que $sp pode ter ovalor alterado durante a execução da função.

♦ Para facilitar o acesso às variáveis estáticas, o registrador$gp (global pointer) é utilizado. Estas variáveis sãoalocadas na região de memória “dados estáticos”, verfigura 3.22 do livro (seção 3.9)

Page 112: Oc2 cap03

Exemplo : $fp e $sp

$sp

Registro deativação

anterior (outrafunção)

Pilha antesda função

$fp

Registradores$s salvos (se

houver)

Registradores$a salvos (se

houver)

$ra salvo

Estruturas evetores locais(se houver)$sp

Registro deativação

anterior (outrafunção)

Pilha duranteexecução da função

$fp

Page 113: Oc2 cap03

0 zero constante 0

1 at reservado para omontador

2 v0 resultados de funções

• v1

4 a0 argumentos

5 a1

6 a2

7 a3

8 t0 temporários: Chamadora

. . . é que deve salvar

15 t7

Registradores MIPS: resumo daconvenção de software

16 s0 Chamada é que deve

. . . salvar

23 s7

24 t8 temporários (cont.)

25 t9

26 k0 reservados para o kernel

27 k1 do sistema operacional

28 gp global pointer

29 sp stack pointer

30 fp frame pointer

31 ra endereço de retorno

Fig. A.10

Page 114: Oc2 cap03

Categoria Instrução Exemplo SemânticaAdição add $s1, $s2, $s3 $s1 = $s2 + $s3AritméticaSubtração sub $s1, $s2, $s3 $s1 = $s2 - $s3Load word lw $s1, 100($s2) $s1 = Mem[$s2 + 100]Transferência

de dados Store word sw $s1, 100($s2) Mem[$s2 + 100] = $s1Branch onequal

beq $s1, $s2, L If ($s1 == $s2) goto L

Branch on notequal

bne $s1, $s2, L If ($s1 != $s2) goto L

DesvioCondicional

Set on lessthan

slt $s1, $s2, $s3 if ($s2 < $s3) $s1 = 1; else $s1 = 0;

Jump j 2500 goto 10000Jump register jr $t1 goto $t1

DesvioIncondicional

Jump & link jal 2500 $ra = PC + 4; goto 10000

Resumo: instruções vistas até agora

Page 115: Oc2 cap03

Trabalhando com caracteres estrings

♦ A maior parte dos computadores hoje utiliza bytes pararepresentar caracteres, quase sempre utilizando acodificação ASCII (American Standard Code forInformation Interchange).

♦ A seção 3.7 traz a tabela ASCII, que deve ser utilizadacomo fonte de consulta.

♦ Instruções de transferência de palavras (lw, sw) sãosuficientes para transferir bytes também. Neste caso,bytes individuais poderiam ser lidos ou escritos, através douso de máscaras, com as instruções e e ou lógicos (serãovistas no capítulo 4).

Page 116: Oc2 cap03

t No entanto, como grande parte dos programasutiliza texto, MIPS fornece instruções específicaspara mover bytes.

t Leitura de bytes:

t load byte (lb): lê um byte da memória,colocando-o nos 8 bits mais à direita de umregistrador

t Ex: lb $t0, 0($sp) # lê byte que está no topo dapilha

Trabalhando com caracteres estrings

Page 117: Oc2 cap03

♦ Escrita de bytes:

♦ store byte (sb): escreve na memória o byte que estános 8 bits mais à direita de um registrador

♦ Ex: sb $t0, 0($sp) # escreve byte no topo da pilha

Trabalhando com caracteres estrings

Page 118: Oc2 cap03

♦ Caracteres são normalmente combinados em strings oucadeias de caracteres, que possuem um número variávelde caracteres.

♦ Existem 3 opções para representar uma string:

♦ A primeira posição da string é reservada paraarmazenar o comprimento da cadeia;

♦ Ex: “casa” = 4 _c_ _a_ _s_ _a_ = 4 99 97 11597

♦ Qual o tamanho máximo da string se cadaposição ocupa um byte?

Trabalhando com caracteres estrings

Page 119: Oc2 cap03

♦ A string é armazenada em uma estrutura, em que umavariável diz o comprimento da cadeia e outra traz oscaracteres que compõe a cadeia;

Ex: “casa” = {4, _c_ _a_ _s_ _a_} = {4, 99 97 115 97}

♦ A última posição de uma cadeia é indicada por umcaractere especial.

Ex: “casa” = _c_ _a_ _s_ _a_ 0 = 99 97 115 97 0

♦ Esta é a representação utilizada pela linguagem C,sendo o marcador de final de string o valor 0.

Trabalhando com caracteres estrings

Page 120: Oc2 cap03

Exemplo: string_copy

♦ Suponha que tenhamos o seguinte código:

void strcpy(char x[], char y[]){

int i;i = 0;while ((x[i] = y[i]) != 0)

i = i + 1;}

Vamos gerar o código correspondente em assembly MIPS.

Page 121: Oc2 cap03

♦ Os endereços base de x e de y estão em $a0 e $a1,enquanto que i está em $s0. Precisamos então preservaro valor de $s0:

strcpy:addi $sp, $sp, -4 # espaço para 1 item napilhasw $s0, 0($sp) # salva $s0

♦ Inicializamos i com 0:

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

Exemplo: string_copy

Page 122: Oc2 cap03

♦ Podemos fazer o laço então; o endereço de y[i] é formadoadicionando i com o endereço base de y:

L1:add $t1, $a1, $s0 # $t1 = endereço de y[i]

♦ Por que não multiplicamos i por 4??♦ y é um vetor de bytes, e não de palavras!!!

♦ Agora carregamos o caractere y[i]:

lb $t2, 0($t1) # $t2 = y[i]

Exemplo: string_copy

Page 123: Oc2 cap03

♦ Preparamos agora o endereço de x[i] em $t3, earmazenamos y[i]:

add $t3, $a0, $s0 # $t3 = endereço de x[i]sb $t2, 0($t3)# x[i] = y[i]

♦ Se o caractere y[i] for 0, saimos do loop:

beq $t2, $zero, L2 # se y[i] == 0, desvie para L2

♦ Senão, incremente i e itere novamante:

addi $s0, $s0, 1 # $s0 = $s0 + 1j L1 # desvie para L1

Exemplo: string_copy

Page 124: Oc2 cap03

♦ Restauramos $s0, ajustamos $sp e retornamos:

• L2: # fim de string• lw $s0, 0($sp) # restaura $s0• addi $sp, $sp, 4 # retira 1 item da

pilha• jr $ra # retorna para

chamador

♦ Poderíamos ter alocado o registrador $t0 para i, e nestecaso não teríamos que empilhar e desempilhar $s0.

♦ Percebemos que é melhor utilizar primeiro osregistradores $t que $s em funções que não chamamoutra função

Exemplo: string_copy

Page 125: Oc2 cap03

Padrão Unicode♦ Está se tornando cada vez mais comum um outro tipo de

codificação para caracteres, o padrão Unicode. Javautiliza este padrão.

♦ Este padrão, além de representar todos os caractereslatinos, pode representar símbolos de letras orientais,dentre outros.

♦ Um caractere passa a ocupar 16 bits. Quantos símbolospodem ser representados?

♦ MIPS inclui instruções para trabalhar com 16 bits, masnão veremos elas neste curso. Quem estiver curioso,consulte o apêndice A do livro.