Вы находитесь на странице: 1из 24

PDF gerado usando o pacote de ferramentas em cdigo aberto mwlib. Veja http://code.pediapress.com/ para mais informaes.

PDF generated at: Wed, 10 Sep 2014 18:22:54 UTC


Introduo Arquitetura de
Computadores
Contedo
Pginas
Capa 1
Introduo 2
O que o MIPS? 4
Instrues do MIPS 5
Representao das Instrues 9
As Pseudo-Instrues 10
Suporte Funes 11
Representao Numrica 14
As Operaes da Unidade Lgica Aritmtica 17
Referncias
Fontes e Editores da Pgina 20
Fontes, Licenas e Editores da Imagem 21
Licenas das pginas
Licena 22
Capa
1
Capa
Introduo Arquitetura de Computadores
Clique aqui para ir ao ndice
Ir para o ndice
A imagem de capa deste wikilivro de uma rplica do Cray-1 - o primeiro supercomputador da histria. A rplica
est em um museu alemo. O Cray-1 foi construdo em 1971 e era mais veloz qque qualquer outro computador da
poca. De fato, demorou dcadas para que surgissem computadores capazes de superar o Cray-1 em velocidade. Ele
era capaz de efetuar 160 milhes operaes aritmticas por segundo e custava U$700.000,00.
O desenvolvimento de uma mquina to rpida s foi possvel graas pesquisas em Arquitetura de Computadores.
A Arquitetura de Computadores cincia de selecionar e interconectar componentes de hardware para produzir
computadores que atendam a requisitos funcionais, de desempenho e custo. Ela tambm pesquisa formas de tornar os
computadores mquinas mais eficientes, baratas e/ou rpidas.
Clique aqui para ir ao ndice
Ir para o ndice
Introduo
2
Introduo
O Que Arquitetura de Computadores
A Arquitetura de Computadores o projeto conceitual e fundamental da estrutura operacional de um sistema
computacional. Ela o estudo dos requisitos necessrios para que um computador funcione e de como organizar os
diversos componentes para obter melhores desempenhos.
Como computador entendemos qualquer tipo de dispositivo capaz de receber uma entrada e que retorna uma sada
aps realizar uma srie de operaes com base nos valores recebidos e armazenados. Existem vrios tipos de
computadores. Uma das formas de classific-los por meio das seguintes categorias:
Desktop: Computadores de baixo-custo e com desempenho razovel para um usurio "comum".
Servidor: Mquinas projetadas para ter um desempenho considerado bom para uma aplicao muito grande e
complexa ou ento para um nmero muito grande de operaes mais simples. Alguns servidores so simples
computadores de Desktop melhorados. Entretanto, existem tambm aqueles que possuem arquiteturas muito mais
sofisticadas que contam com dezenas ou at mesmo centenas de processadores.
Sistemas Embarcados: Possuem um uso dedicado uma nica tarefa e normalmente vem embutidos em outros
aparelhos como celulares, microondas, elevadores ou veculos. Possuem uma Entrada/Sada muito simples.
Os princpios estudados em Arquitetura de Computadores so fundamentais para se projetar mquinas realmente
eficientes.
Computadores e as Vrias Camadas de Abstrao
Computadores so aparelhos extremamente complexos. Para compreender o seu funcionamento, precisamos
entender vrias camadas de abstrao diferente.
A camada mais baixa de todas aquela formada por transistores, tenso e corrente eltrica. Quem costuma lidar com
esta camada so fsicos e engenheiros eltricos. Nesta camada estuda-se o funcionamento de transistores e circuitos
sempre levando em conta as propriedades fsicas da corrente eltrica. Abaixo vemos um desenho representando um
transistor.
Uma camada acima, esto as portas lgicas - todas elas compostas por transistores. Neste nvel estuda-se como criar
estruturas mais complexas combinando-se as diversas portas como AND, OR e NOT para criar estruturas como
multiplexadores, flip-flops e somadores. Neste estgio poode-se usar lingagens como o Verilog ou VHDL para
programar circuitos. Abaixo vemos desenhos que representam vrias portas lgicas:
Introduo
3
Subindo mais um nvel de abstrao, comeamos a lidar com estruturas mais complexas como registradores e
unidades lgicas aritmticas - todas compostas por muitos flip-flops, somadores e multiplexadores. Vemos como
todas essas estruturas realmente geram as instrues de cada mquina e como cada instruo funciona. neste nvel
que costuma trabalhar um Arquiteto. Este ser o nvel que ser abordado ao longo deste Wiki-livro. Abaixo
mostramos a imagem de uma Unidade Lgica Aritmtica - estrutura usada por computadores para realizar clculos:
Um nvel alm, estuda-se como combinar as instrues da camada anterior para realizar comandos mais sofisticados
como as operaes da lingagem C e como coordenar o funcionamento de um sistema operacional por meio de
interrupes e outros recursos. A imagem abaixo um diagrama que representa o Kernel de um Sistema Operacional
sendo usado como um meio de comunicao entre o Software e o Hardware:
Introduo
4
Acima desta camada, est o estudo do funcionamento de funes de bibliotecas, APIs e a programao de aplicativos
e programas de computador simples.E finalmente, na camada de abstrao mais superior est o funcionamento de
um programa de computador do ponto de vista do usurio. Como utilizar um aplicativo j criado.
O que o MIPS?
O Processador MIPS
O MIPS o nome de uma arquitetura de processadores baseados no uso de registradores. As suas instrues tem
disposio um conjunto de 32 registradores para realizar as operaes. Entretanto, alguns destes registradores no
podem ser usados por programadores, pois so usados pela prpria mquina para armazenar informaes teis.
O que o MIPS?
5
Processadores MIPS so do tipo RISC (Reduced Instruction Set Computer - ou seja, Computadores com Conjunto de
Instrues Reduzidas). Isso significa que existe um conjunto bastante pequeno de instrues que o processador sabe
fazer. Combinando este pequeno nmero, podemos criar todas as demais operaes.
Pela sua elegncia e simplicidade, processadores MIPS so bastante usados em cursos de arquiteturas de muitas
universidades. Ele considerado um processador bastante didtico.
Projetos MIPS so atualmente bastante usados em muitos sistemas embarcados como dispositivos Windows CE,
roteadores Cisco e video-games como o Nintendo 64, Playstation, Playstation 2 e Playstation Portable.
A Filosofia do Projeto do MIPS
Quando o MIPS estava sendo desenvolvido, quatro regras foram definidas para guiar o projeto. Elas so a filosofia
do MIPS:
A simplicidade favorece a regularidade.
O menor (quase sempre) mais rpido. Levando em conta que uma corrente eltrica se propaga cerca de um
palmo por nanosegundo, circuitos simples so menores e portanto, mais rpidos.
Um bom projeto demanda compromissos.
O caso comum DEVE ser mais rpido. muito melhor tornar uma instruo que usada 90% do tempo 10%
mais rpida do que fazer com que uma instruo usada em 10% das vezes torne-se 90% mais rpida. Esta regra
baseada na "Lei de Amdahl".
Foram estas as regras usadas para decidir vrios aspectos do funcionamento do MIPS - incluindo quais seriam suas
instrues e como elas funcionariam.
Instrues do MIPS
Vamos comear agora a estudar as instrues que existem em um computador MIPS. Para praticar e testar as
instrues caso voc no tenha uma mquina MIPS usar um simulador como o SPIM. O download do simulador
SPIM para Linux, Mac OS, Unix e Windows pode ser feito no link: [1].
O objetivo deste captulo no fornecer um guia de referncia exaustivo sobre todas as instrues dos MIPS. Iremos
apenas apresentar um sub-conjunto mnimo de todas as instrues do MIPS que so o mnimo necessrio para termos
um computador funcionando.
Instrues Aritmticas Simples
add $r1, $r2, $r3 # Esta instruo soma o contedo dos registradores
# $r2 e $r3 colocando o contedo no registrador $r1
addi $r4, $r1, 9 # Agora estamos somando o contedo do registrador
# $r1 com o valor imediato 9 e armazenando o
# resultado em $r4. O nmero imediato deve ter
# 16 bits.
addu $r5, $r6, $r4 # Quase igual ao add. Mas agora assumimos que
# todos os valores so no-negativos.
addiu $r7, $r8, 10 # Somamos o contedo de $r8 com o valor imediato
# 10 e armazenamos o resultado em $r7. Assume-se
Instrues do MIPS
6
# que todos os valores so no-negativos.
sub $r1, $r2, $r3 # Subtrai-se o contedo de $r3 do contedo de $r2
# e coloca-se em $r1. Tambm existe subi, subu e
# subiu que tem comportamento semelhante a addi,
# addu e addiu, mas para a subtrao.
Instrues de Operadores Lgicos
and $r1, $r2, $r3 # Realiza uma operao AND bit-a-bit entre $r3 e $r2.
# O resultado armazenado em $r1.
andi $r1, $r2, 42 # Realiza uma operao AND bit-a-bit entre $r2 e o valor
# imediato 42. O resultado armazenado em $r1. O nmero
# imediato deve caber em 16 bits.
or $r1, $r2, $r3 # Realiza uma operao OR bit-a-bit entre $r3 e $r2.
# O resultado armazenado em $r1.
ori $r1, $r2, 42 # Realiza uma operao OR bit-a-bit entre $r2 e o valor
# imediato 42. O resultado armazenado em $r1. O nmero
# imediato deve caber em 16 bits.
Podemos notar que as instrues seguem uma lgica clara. At agora todas seguem uma mesma lgica. Alm destas,
no existem instrues mais complexas como potncias ou razes quadradas.Somente as operaes matemticas mais
simples so representadas. Podemos ver aquelas 4 regras que formam a filosofia do projeto do MIPS em ao.
Instrues de Uso de memria
As instrues do uso da memria seguem uma lgica diferente das instrues de operaes aritmticas. Pra comear,
existem trs tipos de instrues capazes de copiar dados da memria para os registradores.
lw $r1, 4($r2) # Load Word: Esta instruo carrega uma palavra (estrutura de 4 bytes)
# localizada no endereo representado pela soma do valor
# armazenado no registrador $r2 mais 4. O resultado armazenado em $r1.
lh $r1, 6($r3) # Load Half: Esta instruo carrega uma estrutura de 2 bits localizada
# no endereo representado pela soma do valor armazeado no
# registrador $r3 mais o nmero 6. O resultado armazenado em $r1.
lb $r1, 16($r2)# Load Byte: Esta instruo carrega um byte (8 bits) localizado no
# endereo representado pela soma do valor armazenado em $r2 mais o
# nmero 16. O resultado armazenado em $r1.
Perceba que desta forma rpido de carregar o contedo de um valor em um vetor. Basta saber o endereo do valor
inicial do vetor e o ndice de sua posio. Por exemplo, suponha que eu possua um vetor de caracteres char vetor[5].
Supondo que o registrador $r1 contenha o endereo de vetor[0], para armazenar o valor de vetor[3] no registrador
$r2 e assumindo que cada caractere possui um byte, basta usar a seguinte instruo:
lb $r2 24($r1)
Instrues do MIPS
7
Colocamos o 24 l porque cada caractere ocupa 8 bits e queremos pegar o quarto caractere da seqncia. Logo,
precisamos nos deslocar 24 bits para acharmos o caractere certo. Afinal, a distncia entre o primeiro elemento do
vetor armazenado em $r1 e o quarto item do vetor de 24:
[0][ ][ ][ ][ ][ ][ ][ ].[1][ ][ ][ ][ ][ ][ ][ ].[2][ ][ ][ ][ ][ ][ ][ ].[3][ ][ ][ ][ ][ ][ ][ ]
Para armazenarmos contedo de um registrador na memria tambm existem 3 comandos:
sw $r1, 4($r2) # Store Word: Esta instruo carrega uma palavra (estrutura de 4 bytes)
# localizada no registrador $r1 e armazena no endereo representado
# pela soma do valor armazenado no registrador $r2 mais 4.
sh $r1, 4($r2) # Store Half: Esta instruo carrega uma estrutura de 2 bits
# localizada no registrador $r1 e armazena no endereo representado
# pela soma do valor armazenado no registrador $r2 mais 4.
sb $r1, 4($r2) # Store Byte: Esta instruo carrega um byte (8 bits)
# localizado no registrador $r1 e armazena no endereo representado
# pela soma do valor armazenado no registrador $r2 mais 4.
Vamos ver um exemplo de converso de um cdigo escrito em C para a lingagem Assembly do MIPS assumindo
que um int da lingagem C tenha 4 bits:
/* CDIGO C */
typedef struct A{
int x;
int y;
int z;
int w;
}aType;
aType V[16];
(...)
aPtr = &(V[3]);
m = aPtr -> y;
n = aPtr -> w;
aPtr -> x = m + n;
Vamos assumir que o vetor V esteja no endereo 0x0800.0000. A estrutura aType formada por 4 valores numricos
consecutivos, cada um com 4 bits. Logo, cada aType ocupa 16 bits (4*4). Ou, em hexadecimal, 0x010 bits. Veja uma
representao de um aType como armazenado na memria:
[x][x][x][x][y][y][y][y][z][z][z][z][w][w][w][w]
Temos um vetor com 16 estruturas como esta chamado V. Logo, o vetor ocupa um espao de 256 bits. Com estas
informaes, conclumos que o cdigo em Assembly necessrio para fazer a operao mostrada no cdigo em C
mostrado acima :
Instrues do MIPS
8
la $r1, 0x0800.0030 # A instruo Load Address carrega em $r1 o endereo de V[3]. Falaremos sobre o la depois.
lw $r2, 4($r1) # Carregamos para $r2 o quarto bit partir de V[3]. Ou seja, o valor de y.
lw $r3, 12($r1) # Agora carregamos para $r3 o valor do inteiro w.
add $r4, $r2, $r3 # Somamos os valores de y e w colocando o valor em $r4.
sw $r4, 0($r1) # Colocamos o valor da soma no lugar do x.
Instrues de Controle de Fluxo
Agora veremos instrues capazes de controlar o fluxo de execuo de instrues de um computador. A primeira
delas a instruo beq, ou Branch if Equal:
beq $r1, $r2, DESTINO
O que esta instruo faz verificar se o valor de $r1 igual $r2. Caso isso seja verdadeiro, ela muda o valor do
registrador PC (Program Counter) que guarda o endereo da prxima instruo a ser executada. Se o valor passado
como destino for 0, nada acontece. Nenhuma instruo pulada, o programa executa a prxima instruo
normalmente, independente de $r1 == $r2 ser verdadeiro ou falso. Se o valor passado for "1", pula-se uma instruo
se $r1 for igual a $r2. Se o valor passado for "2", pulam-se duas instrues e assim por diante. Tambm pode-se
passar valores negativos. Um valor de "-1" faz com que o programa entre em um loop infinito, nunca mais passando
para a prxima instruo. Uma "-2" faz com que voltemos uma instruo anterior, e assim por diante.
Entretanto, o valor de DESTINO s pode ser no mximo um valor com 16 bits. Com um valor destes, s podemos
pular no mximo cerca de 32 000 instrues para frente ou para trs. Isso no um problema na maioria das vezes
muito raro existir um programa que exija que voc pule uma quantidade to grande de instrues. Assumindo que 4
linhas de cdigo e Assembly correspondem a 1 linha em cdigo C, para que pulemos uma quantidade to grande de
instrues, teramos que fazer um if com um bloco com mais de 8.000 linhas de cdigo. Isso algo extremamente
difcil de ocorrer em um programa real.
Mas caso voc realmente precise pular mais de 32 000 instrues, isso perfeitamente possvel, desde que voc
altere antes o valor do registrador PC. Com isso, perde-se um pouco de desempenho, mas torna desvios de cdigo
extremamente grandes possvel. E o importante que o caso comum (programas em C com blocos menores de 8.000
linhas) roda mais rpido (regra 4 da Filosofia de Projeto do MIPS).
Alm do beq, temos tambm o bne, ou Branch if Not Equal:
bne $r1, $r2, DESTINO
Ele funciona da mesma forma que o beq. A diferena que ele pula um determinado nmero de instrues somente
se o valor dos dois registradores for diferente.
E finalmente, temos a instruo j, ou Jump:
j ENDEREO
Ele faz com que o programa passe a executar a instruo que encontrada no endereo dado. O endereo passado
para a instruo j sempre um nmero de 26 bits. Entretanto, os endereos da mquina sempre so nmeros de 32
bits. Ento como ser possvel saber qual o endereo em que est a instruo desejada?
muito simples. Instrues sempre estaro em endereos mltiplos de 4. Ento sabemos que os dois ltimos bits do
endereo so sempre 0. No precisamos armazen-los. J os dois primeiros bits, retiramos do PC, pois sempre
muito mais provvel que ns usemos o controle de fluxo para saltar para uma posio no muito distante. Caso
precisemos saltar para um posio muito distante, basta alterarmos o valor do PC primeiro. Da mesma forma que foi
visto no beq, o caso comum executa mais rpido desta forma. Isso muito bom, mesmo que tenhamos mais trabalho
e perda de desempenho nas pouqussimas vezes nas quais precisamos dar saltos muito longos.
Instrues do MIPS
9
Instrues de Comparaes
Por fim, precisamos ver ainda instrues de comparao. Um exemplo o slt, ou Set Less Than:
slt $r1, $r2, $r3
Ela armazena 1 em $r1 se $r2 < $r3 e 0 caso contrrio.
Resumo dos Modos de Endereamento
Nas instrues do MIPS podemos representar os endereos de dados das seguintes formas:
A Registrador: Representamos o dado passando o nome do registrador no qual ele est contido. Ex: add $r1,
$r2, $r2.
Base-Deslocamento: Representamos o dado passando o endereo de um vetor no qual ele est e a quantidade de
bits a serem deslocados. Ex: lw $r5, 4($r65).
Imediato: Passamos o dado escrevendo o seu valor imediato. Ex: addi $r1, $r2, 456.
Relativo ao PC: Passamos o dado descrevendo o seu valor relativo ao endereo da instruo atual. Ex: beq $r1,
$r2, DESTINO.
Absoluto: passamos o valor informando o seu endereo (pseudo-)absoluto. Ex: j DESTINO.
Existem apenas estas 5 formas de endereamento no MIPS. Atravs delas, efetuamos todas as operaes necessrias.
Referncias
[1] http:/ / pages.cs.wisc. edu/ ~larus/ spim.html
Representao das Instrues
Sabemos que tudo dentro do computador representado por meio de bits - que podem ter o valor de 0s e 1s. At
mesmo as instrues de um processador MIPS. Vamos estudar agora como uma instruo representada a nvel de
bits. O MIPS reconhece 3 famlias diferentes de instrues. So elas:
As Instrues Tipo R
Como exemplo de instrues do tipo R vistas, temos: add, addu, sub, subu, or e and.
Elas so codificadas da seguinte forma:
[o][o][o][o][o][o] - [u][u][u][u][u] - [t][t][t][t][t] - [d][d][d][d][d] - [s][s][s][s][s] - [f][f][f][f][f][f]
Onde a letra "o", representa o opcode, ou Cdigo de Operao. Ele avisa mais-ou-menos o que a instruo vai fazer.
Por exemplo, uma instruo de soma add muito semelhante instruo xor que faz um XOR lgico bit-a-bit. A
nica diferena que na soma, devemos armazenar um bit a mais para representar o "vai um" quando somamos 1+1.
Logo, as duas instrues tem o mesmo opcode.
As letras "u" e "t" representam os operandos das instrues. Ou melhor, os registradores nos quais esto os
operandos.
A letra "d" o registrador de destino onde deve ser armazenado o resultado.
A letra "s" ou Shampt representa o deslocamento de bits, ou seja um shift que pode se usado aps a operao.
Finalmente, a letra "f" o cdigo de funo. por meio dela que diferenciamos instrues semelhantes que tem o
mesmo opcode, como add e or.
Representao das Instrues
10
As Instrues Tipo I
Como exemplo deste tipo de instruo, podemos citar todas aquelas que contam com um valor imediato, como addi,
subi, ori, beq e bnq.
Eles so codificados da seguinte forma:
[o][o][o][o][o][o] - [u][u][u][u][u] - [t][t][t][t][t] - [i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i]
A letra "o" representa o cdigo da instruo. A letra "u" represeenta o nmero do registrador onde a o resultado da
operao colocado. J a letra "t" representa o nmero do registrador em que est um dos operandos. J o "i"
representa o nmero imediato. Agora vemos o porqu do valor passado como imediato nunca poder exceder os 16
bits.
As Instrues Tipo J
A nica instruo vista no captulo anterior do tipo J a j. Ela codificada da seguinte forma:
[o][o][o][o][o][o] - [d][d][d][d][d][d][d][d][d][d][d][d][d][d][d][d][d][d][d][d][d][d][d][d][d][d]
O "o" representa o cdigo da operao j e d representa o destino.
As Pseudo-Instrues
A linguagem Assembly de uma mquina costuma ser um reflexo direto de como so implementadas as instrues de
um determinado processador. Entretanto, nem todas as instrues que temos disposio quando programamos em
Assembly so instrues verdadeiras para o processador. Algumas delas so na verdade pseudo-instrues.
Pseudo-instrues costumam ser substitudas pelo montador ao gerar instrues para o computador na forma de
Lingagem de Mquina. Pseudo-Instrues so na verdade combinaes de mais de uma instruo. Vejamos agora
alguns exemplos:
A Pseudo-Instruo move
move $r1, $r2 # Copia o contedo do registrador $r2 para $r1
Ela na verdade implementada da seguinte forma:
addu $r1, $r0, $r2 # Soma $r2 com zero e coloca o resultado em $r1
O registrador $r0 usado acima no um registrador comum. Ele sempre possui o valor "0" e um dos poucos
registradores cujo valor nunca pode ser alterado pelo programador.
As Pseudo-Instrues
11
A Pseudo-Instruo Load Address
la $r1, ENDEREO # Coloca o valor numrico de 32 bits "ENDEREO" em $r1
Esta instruo muito til para fazeer registradores receberem o valor de ponteiros para outros locais de memria.
De fato, usamos esta pseudo-instruo no Captulo anterior quando convertemos um cdigo em C para o Assembly
do MIPS. Ela na verdade implementada desta forma:
lui $r1, constHI # Carrega-se os 16 bits mais significativos em $r1
ori $r1, $r0, constLO # Executa-se um OR bit-a-bit entre o registrador
# com os 16 bits mais significativos e os 16 bits
# menos significativos
O que a instruo lui, ou Load Upper Immediate faz uma operao shift de 16 bits para a esquerda e coloca no
registrador indicado. Este passo necessrio porque valores imediatos passados para instrues s podem ter 16 bits
por causa da limitao de espao das instrues do Tipo I.
Tambm existe a instruo li, ou Load Immediate que faz exatamente a mesma coisa que o la.
Note que o montador que remove as pseudo-instrues e as substitui por instrues que realmente existem no
hardware sempre podem verificar se o valor que queremos carregar no registrador cabe em 16 bits. Neste caso, a
instruo gerada fica bem mais simples e rpida:
addu $r1, $r0, $r2 # Soma $r2 com 0 e coloca em $r1
Suporte Funes
Funes so ferramentas muito importantes, pois tornam cdigo escrito muito mais usvel e torna a tarefa de
programar mais produtiva. Elas permitem que um programador se concentre em apeenas uma tarefa de cada vez.
Portanto, essencial que um processador possua suporte elas. Veremos como isso ocorre no MIPS.
As Etapas Necessrias para Invocar Funes
Quando queremos chamar uma funo, as seguintes etapas devem ser cumpridas:
O programa principal deve colocar os parmetros da funo em um local que ela possa acessar.
O programa principal deve ceeder o controle para a funo.
A funo deve coletar todos oos parmetros deixados pelo programa principal.
A funo deve executar a tarefa desejada.
A funo deve aramazenar seus resultados em um lugar em que o programa principal possa acessar.
A funo deve retornar o fluxo do cdigo para o ponto imediatamente aps ser chamada.
Para que estes requisitos sejam cumpridos, as seguintes convenes fora criadas:
Os registradores $r4, $r5, $r6 e $r7 seriam usados para armazenar parmetros de funes. Por causa desta
funcionalidade, tais registradores podem ser chamados pelos seus "apelidos": $a0, $a1, $a2 e $a3.
Os registradores $r2 e $r3 seriam usados para as funes armazenarem seus valores de retorno para o programa
principal. Por isso, eles costumam ser chamados de $v0 e $v1.
Tais regras so apenas convenes. Nada impede que um programador as desrespeite e use outros registradores para
estabelecer comunicao entre funes e programas principais. Entretanto, para que um programa funcione bem em
conjunto com todos os demais, importante quee tais convenes sejam seguidas.
Suporte Funes
12
Alm dos registradores convencionados acima, o registrador $r31 tambm tem um papel importante. Ele sempre
armazena o endereo de retorno para o qual a ltima funo chamada deve retornar. Por ter uma funo to
importante, este registrador mais conhecido pelo apelido $ra.
Instrues de Uso de Funes: jal e jr
A instruo que usamos para invocar uma funo chama-se jal, ou Jump and Link. Ela usada da seguinte forma:
jal ENDEREO_DA_FUNO
Entretanto, s devemos chamar esta funo depois de j termos salvo os argumentos nos registradores apropriados.
Depois da funo executar todas as operaes e salvar os resultados apropriados em $v0 e $v1, podemos usar a
instruo jr, ou Jump Register. Normalmente usamos a instruo passando para ela o valor do registrador $ra, que
contm o endereo certo para voltarmos:
jr $ra
Como exemplo de como isso pode ser feito, vamos converter para Assembly o seguinte cdigo em C:
int example(int a, int b, int c, int d){
int f;
f = (a + b) - (c + d)
return f;
}
O cdigo no Assembly do MIPS ficaria assim:
example: # Label
add $t0, $a0, $a1 # Soma a + b
add $t1, $a2, $a3 # Soma c + d
sub $v0, $t0, $t1 # Subtrai os dois valores e coloca o resultado no registrador de retorno
jr $ra # Retorna o controle para a funo principal
Entretanto, observe que para realizarmos os clculos necessrios, precisamos usar registradores. Ao fazer isso, existe
o grande risco de apagarmos dados importantes do programa principal. Para evitar isso, existe uma conveno que
diz que os registradores $r8 at $r15, $r24 e $r25 so registradores temporrios. Por isso, eles costumam ser
chamados de $t0 at $t9. Aps chamar uma funo, o programa principal no deve esperar que os valores destes
registradores sejam os mesmos. Somente dados que estejam nos registradores $r16 at $r23 so sempre preservados
entre funes. Por esta razo, tais registradores permanentes (salvos) so chamados de $s0 at $s7.
Funes com Muitas Variveis
Existem funes que podem precisar receber mais do que 4 parmetros. Entretanto, s temos registradores
suficientes para armazenar 4 parmetros. Ns tambm podemos querer retornar mais do que os 2 valores permitidos
pelos registradores. Ou ento, nossa funo pode precisar armazenar mais do que 10 valores temporrios. O que
fazer para resolver isso?
Como o espao dentro de registradores bastante limitado, s nos resta apelar para a pilha da memria. Por
conveno, o registrador $r29, ou $sp (Stack Pointer) armazena o endereo na pilha de onde novos valores podem
ser colocados. Acessando seu endereo e alterando-o podemos guardar valores na memria. O acesso pilha da
memria muito mais lento que o acesso registradores, mas este o nico modo de podermos armazenar uma
quantidade muito maior de informao.
Suporte Funes
13
Por motivos histricos, a pilha "cresce" sempre dos valores de endereos altos para valores menores. Ou seja, para
alocar espao para mais valores, precisamos sempre decrementar o seu valor. Incrementando-o, estamos na verdade
removendo os ltimos dados da pilha.
Vamos reescrever agora o cdigo Assembly visto acima, desta vez preeservando os valores dos registradores $t0 e
$t1 para vermos como ficaria o resultado:
example: # Label
addi $sp, $sp, -8 # Alocamos espao para dois valores de 4 bits.
sw $t1, 4($sp) # Preservamos o valor de $t1 partir do 4o bit aps o Stack Pointer
sw $t0, 0($sp) # Preservamos o valor de $t0 sobre o Stack Pointer
add $t0, $a0, $a1 # Soma a + b
add $t1, $a2, $a3 # Soma c + d
sub $v0, $t0, $t1 # Subtrai os dois valores e coloca o resultado no registrador de retorno
lw $t0, 0($sp) # Retiramos o valor antigo salvo de $t0
lw $t1, 4($sp) # Retiramos da pilha o valor antigo de $t1
addi $sp, $sp, 8 # Voltamos o Stack Pointer para a posio original apagando de vez as variveis locais
jr $ra # Retorna o controle para a funo principal
Funes Recursivas e Sub-Funes
Da mesma forma que o programa principal invocou uma funo, uma funo tambm pode invocar outras funes.
Se la for recursiva, ela pode at mesmo invocar clones de si mesma para realizar uma tarefa. Como implementar isso
sendo que temos apenas um registrador $ra? Se chamarmos outra funo, o $ra original sobrescrito e podemos
perder a capacidade de voltar ao programa principal. Alm disso, valores temporrios que representam variveis
locais podem ser perdidos.
A nica forma de evitar isso enviar para a pilha tudo aquilo que precisa ser salvo - da mesma forma que fizemos
com alguns valores no exemplo acima. Para mostrar isso na prtica vamos implementar em Assembly a seguinte
funo em C:
/* Calcula Fatorial */
int fat(int n){
if(n < 1)
return 1;
else
return (n * fat(n - 1));
}
O resultado final algo como:
fat: # Incio da funo
addi $sp, $sp, -8 # Aloca espao na pilha para 2 valores
sw $ra, 4($sp) # Guarda valor de retorno na pilha
sw $a0, 0($sp) # Guarda primeiro argumento na pilha
slti $t0, $a0, 1 # $t0 = ( $a0 < 1)
beq $t0, $zero, L1 # Se $a0 >= 1, v para L1
addi $v0, $zero, 1 # Seno, coloque 1 como valor de retorno
addi $sp, $sp, 8 # Apague as duas variveis locais salvas na pilha
jr $ra # Encerra a funo
L1: addi $a0, $a0, -1 # Se $a >= 1, decremente $a0
Suporte Funes
14
jal fat # Chame um clone recursivo de fat que retorna fat($a0-1)
lw $a0, 0($sp) # Recupere os valores iniciais do parmetro da funo
lw $ra, 4($sp) # Recupere o endereo de retorno antigo
addi $sp, $sp, 8 # Apague as duas variveis locais salvas na pilha
mul $v0, $a0, $v0 # Coloque $a0 * fat($a0 - 1) como valor de retorno
jr $ra # Encerra a funo
Por fim, uma ltima coisa til que interessante comentar que o Stack Pointer ($sp) pode ser alterado vrias vezes
ao longo de uma funo. Para manter memorizado o valor do endereo da pilha no incio da funo, costuma-se usar
o registrador $r30 como um Frame Pointer ($fp). Nos exemplos acima, isso no foi preciso, pois s mudamos o
valor do Stack Pointer no comeo e fim de cada funo. Mas em alguns programas utilizar este registrador pode ser
til.
Representao Numrica
Nmeros podem ser representados em qualquer tipo de base. Humanos costumam representar nmeros na base
decimal. Esta possui este nome por possuir 10 dgitos diferentes: 0, 1, 2, 3, 4, 5, 6, 7, 8 e 9.
Como computadores s so capazes de reconhecer dois tipos diferentes de estados, natural para eles representar
nmeros na base binria. Ou seja, eles s compreendem os valores "0" e "1". Vamos ver agora coo podemos
representar diversos tipos de nmeros usando apenas dois tipos diferentes de sinais.
Nmeros Naturais
Representar Nmeros Naturais simples bastante simples - mesmo quando s podemos usar dois tipos diferentes de
sinais. O 0 decimal representado como 0. O 1 decimal tambm representado como 1. J o 2 decimal
representado com "10". Enfim, quando contamos os nmeros naturais na base binria, fazemos da seguinte forma:
BASE |
BINRIA | 0 1 10 11 100 101 110 111 1000 1001 1010
|
BASE |
DECIMAL | 0 1 2 3 4 5 6 7 8 9 10
Quando representamos nmeros desta forma, no temos nmeros negativos. Logo, nenhum nmero possui sinal
algum. Por isso, chamamos tais nmeros de unsigned (sem sinal).
Atualmente, a maioria das mquinas possui representao numrica 32 bits. Isso significa que seus nmeros so
compostos por 32 dgitos. Com uma representao destas, o menor nmero binrio sem sinal que podemos
representar 00000000000000000000000000000000 e o maior 1111111111111111111111111111111.
Convertemos tais valores para decimal, chegamos concluso que a maioria dos computadores s lida com nmeros
sem sinal cujo valor esteja entre 0 e 4.294.967.295 - que so os equivalentes decimais destes nmeros.
Para descobrir qual o equivalente decimal de um nmero binrio de 32 bits, usa-se a frmula abaixo:
onde o dgito mais significativo e o bit menos significativo.
Representao Numrica
15
Nmeros Inteiros
Nem sempre os nmeros com os quais queremos lidar so naturais. Pode haver necessidade de realizarmos operaes
com nmeros negativos. Para tal, devemos encontrar uma forma de representarmos nmeros negativos. Uma das
primeiras formas tentadas de fazer isso foi reservando o primeiro bit de um nmero para representar o sinal. Assim,
um 0000000 (...) 001 representa +1 e um 10000 (...) 001 representaria um -1. Entretanto, tal forma de representao
j foi abandonada h muito tempo. Um dos principai motivos para o abandono desta representao est no fato de
sempre termos que verificar o primeiro bit para descobrir como efetuar uma soma ou subtrao entre dois nmeros.
Alm disso, tal representao tornaria possvel um "+0" e um "-0".
A forma de se representar nmeros inteiros em computadores modernos chamada de Representao em
Complemento de 2. Ela feita da seguinte forma:
Os 31 bits mais esquerda representam sempre nmeros positivos. Calculamos o que eles representam com a mesma
frmula vista acima. Entretanto, o primeiro bit representa sempre "0" se o seu valor for "0" ou " se o seu valor
for "1". Assim, a frmula para se calcular o que representa um nmero binrio inteiro em decimal :
onde o dgito mais significativo e o bit menos significativo.
A representao em complemento de 2 boa pelos seguintes motivos:
Para somar dois nmeros inteiros, usa-se o mesmo mtodo. No precisamos verificar o sinal deles. Com isso,
podemos criar um circuito mais rpido.
Descobrir o inverso de um nmero tambm simples. Basta invertermos todos os bits e, em seguida, somarmos 1.
Sempre funciona.
O "0" sempre "0". No existe uma verso negativa ou positiva deste nmero.
Por meio desta notao, nmeros to pequenos como -4.294.967.296 e to grandes como 4.294.967.295 podem ser
representados.
Nmeros Reais
Por fim, tambm muito til que computadores possam representar nmeros reais. Vamos estudar agora como eles
costumam ser representados em computadores.
A forma mais lgica e verstil de representarmos um nmero real por meio da notao cientfica. Um nmero
decimal em notao cientfica sempre toma a seguinte forma:
onde N sempre um nmero real maior ou igual 1 e menor que 10 que pode ser positivo ou negativo enquanto M
um nmero inteiro qualquer (que pode ser positivo ou negativo). Por exemplo:
representa aproximadamente quantos segundos existe em um sculo enquanto
representa quantos segundos existem em um nanossegundo.
Alternativamente, podemos representar tambm nmeros em notao cientfica utilizando uma base binria:
. Lembre-se que aquele "10" significa na verdadee "2" em representao decimal. Ou seja, o
nmero representado na verdade 0,5 e no 0,1.
Enfim, quando temos um nmero em notao cientfica binria, ele sempre tem a seguinte forma:
, onde "S" representa o sinal (que pode ser positivo ou negativo), "XXXXX" so
a parte fracionria do nmero e "YYYYYY" representa o expoente.
Ento, para representarmos nmeros reais, precisamos representar no espao de 32 bits os valores do sinal, frao e
expoente. No MIPS, isso feito da seguinte forma:
Representao Numrica
16
S -- E E E E E E E E -- F F F F F F F F F F F F F F F F F F F F F F F
O Sinal representado em um nico bit (1 para negativo e 0 para positivo), o expoente representado por 8 bits e a
frao representada por 23 bits. Assim, o exemplo (ou 1/2 em decimal) representado:
0 -- 1 1 1 1 1 1 1 1 -- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Com esta representao, nmeros quase to pequenos como ou quase to grandes como podem ser
armazenados.
Entretanto, note que a nossa preciso no perfeita. Existem muitos nmeros que no podem ser representados desta
forma. Por isso, sempre preciso realizar arredondamentos. E quanto mais operaes realizamos, mais erros acabam
sendo acumulados. Por essa razo, a maioria dos computadores possui tambm uma forma mais precisa de
representao de nmeros reais. Essa forma normalmente ocupa o dobro do espao do que costuma ocupar. No
MIPS uma representao desti tipo ocupa 64 bits. Ela funciona da seguinte forma:
S -- E E E E E E E E E E E -- F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F
Apesar de gastarmos o dobro do espao de armazenamento desta forma, aumentamos consideravelmente a faixa de
valores representados e a preciso com a qual podemos represent-los.
Overflow e Underflow
Overflow o nome do resultado incorreto ao qual chegamos quando tentamos somar nmeros grandes demais e o
resultado no pode ser armazenado e nem representado em 32 bits. Ele pode ocorrer quando efetuamos as seguintes
operaes:
Somamos dois nmeros positivos
Somamos dois nmeros negativos
Subtramos um nmero negativo de um positivo.
de responsabilidade do hardware sempre verificar se ocorreu um overflow nestes casos. Normalmente, para fazer a
verificao basta conferir os sinais dos nmeros. Em caso afirmativo, ele deve ativar um sinal de exceo. O que
feito caso uma excesso seja detectada depende de cada programa.
O MIPS, por exemplo, sempre armazena o endeereo da ltima instruo que gerou excesso em um registrador
especial chamado EPC. A instruo mfc0 (Move from System Control) usada para copiar este endereo para um
registrador de propsito geral que pode ser conferido por algum programa. Cabe ao programador deste programa
decidir o que fazer.
Em lingagens de alto nvel, o comportamento depende da lingagem usada. C, por exemplo, ignora todos os
Overflows. Ao contrrio de Fortran ou Ada que requerem que o programa sempre seja avisado.
Underflow o que acontecee quando lidamos com um nmero real to prximo de 0 que o valor do expoente no
pode ser corretamente representado. Quando um programa requer uma preciso to grande assim, recomenda-se o
uso de pontos flutuantes de dupla preciso (double) para evitar este inconveniente.
As Operaes da Unidade Lgica Aritmtica
17
As Operaes da Unidade Lgica Aritmtica
Computadores so mquinas de calcular. Logo, fundamental que eles sejam capazes de realizar operaes bsicas
como adio, subtrao, diviso e multiplicao. Vamos ver agora como tais operaes so implementadas dentro da
Unidade Lgica Aritmtica de um Processador (ULA).
A Adio e Subtrao
A Adio uma das operaes mais simples. Um computador realiza ela de uma maneira semelhante usada por
ns humanos. Ele comea somando os bits menos significativos. Caso tenha que somar "1" e "1", o resultado fica
sendo "0" e passamos um "vai-um" para o bit esquerda. Veja abaixo um desenho de um circuito capaz de somar
dois nmeros de 8 bits:
Embora a imagem mostre apenas um circuito que soma dois nmeros de 8 bits, no muito difcil perceber que a
lgica para fazer um somador a mesma, tanto para nmeros com 8 como para 32 bits. Basta adicionar mais
somadores. Perceba que o circuito tambm capaz de detectar a presena de Overflow no caso de operaes com
nmeros sem sinal.
Ele pode ser usado tanto para somar nmeros com ou sem sinal. Graas representao de nmeros inteiros por
complemento de dois, no difcil conseguir isso.
O mesmo circuito acima tambm pode ser reaproveitado para realizar subtraes. Basta inverter antes todos os bits
do segundo operando e somar 1 ele. Com isso, estamos na verdade somando o primeiro operando com o negativo
do segundo operando.
As Operaes da Unidade Lgica Aritmtica
18
A Multiplicao
Vamos agora estudar como construir um circuito capaz de realizar multiplicaes. Primeiro vamos tentar realizar
uma multiplicao pelo mtodo convencional que usamos atravs de papel e caneta. Isso pode nos dar uma pista de
como fazer uma operao de multiplicao. Vamos usar a base binria:
1000
x1001
----
1000
00000
000000
1000000
-------
1001000
Perceba que a multiplicao um conjunto de somas. Sempre estamos somando o valor 0 ou o valor do
multiplicador aps este passar por uma operao de SHIFT para a esquerda. O que determina se o que iremos somar
um 0 ou o valor do multiplicador aps um SHIFT so os bits do multiplicando. Se o bit da posio n for um 0,
somamos 0 e se for 1, somamos com o valor do multiplicando "shiftado" n vezes.
Um exemplo de um circuito seqencial capaz de somar dois nmeros de 4 bits mostrado na imagem abaixo:
Note que multiplicando nmeros de 4 bits, ns precisamos armazenar os 8 bits possveis para o resultado. Afinal, o
resultado de uma multiplicao capaz de ter o nmero de bits igual soma dos multiplicandos. Mquinas MIPS
lidam com o problema dividindo o resultado pela metade. os bits mais significativos terminam em um registrador
chamado Hi e os menos significativos acabam em um registrador chamado Lo.
Entretanto, o circuito conforme mostrado acima tem muitos problemas. O principal que ele muito complexo.
Perceba que o circuito para multiplicar nmero de 4 bits pelo menos 3 vezes mais complexo e lento que o usado
para realizar a adio de 8 bits (afinal, o circuito de multiplicao precisa realizar a adio de 3 pares de valores de 8
bits). Um circuito destes para calcular a multiplicao de nmeros com um valor ainda maior de bits seria ainda mais
complexo que isso.
Com isso, chegamos concluso que a multiplicao uma operao complexa demais para ser efetuada por meio
de uma simples lgica combinacional de portas lgicas. Um circuito de multiplicao combinacional seria muito
caro e esquentaria demais. Por isso, sua velocidade teria que ser sacrificada aumentando a distncia dos transistores.
Por isso, utilizam-se circuitos seqenciais para realizar esta operao.
As Operaes da Unidade Lgica Aritmtica
19
O diagrama abaixo mostra descreve o funcionamento de um circuito seqencial capaz de realizar a multiplicao:
O que acontece no diagrama acima no caso de multiplicarmos dois nmeros de 32 bits o seguinte:
1- O "Produto" um registrador inicializado em 0.
2- O produto e o multiplicando so passados para a ULA que soma os dois.
3- O resultado (o valor do prprio multiplicando) pode ir para o registrador "Produto" ou no. Quem toma a
deciso o "Controle".
4- Se o ltimo bit do Multiplicador for "1", o Controle permite a escrita do registrador "Produto". Se for "0", ele
impede.
5- O Multiplicando sofre um shift para a esquerda e o Multiplicador um Shift para a direita.
6- Se a 32a vez que voc chega esta instruo, encerre. A multiplicao terminou. Caso contrrio, volte ao
passo 2.
O diagrama acima j uma forma bem melhor de multiplicarmos. Mas ainda existem otimizaoes que podem ser
feitas para acelerarmos ainda mias a multiplicao:
Podemos utilizar um nico registrador de 64 bits para armazenar tanto o multiplicador como o produto. O
multiplicador vem antes e o produto logo depois. Assim, cada vez que fazemos um shift para a direita no
multiplicador, aproveitamos o espao liberado mais esquerda para colocar um novo bit do produto. Desta forma,
no necessrio somar nmeros de 32 bits, apenas somar o suficiente para descobrir qual o prximo bit do
produto a ser colocado.
Compiladores substituem multiplicao por potncias de 2 por operaes de shift que so mais rpidas.
Para multiplicaes envolvendo nmeros negativos, basta invetermos os nmeros transformando-os em positivos.
Em seeguida, fazemos a multiplicao normalmente e observamos os sinais do multiplicador e multiplicando. Se
forem iguais, masntemos os nmeros como positivos. Caso contrrio, convertemos o produto para negativo.
Fontes e Editores da Pgina
20
Fontes e Editores da Pgina
Capa Fonte: http://pt.wikibooks.org/w/index.php?oldid=204857 Contribuidores: Master, Raylton P. Sousa, 1 edies annimas
Introduo Fonte: http://pt.wikibooks.org/w/index.php?oldid=239231 Contribuidores: Master, Raylton P. Sousa, Thiagoharry, 5 edies annimas
O que o MIPS? Fonte: http://pt.wikibooks.org/w/index.php?oldid=199789 Contribuidores: GrooveDog, Master, Raylton P. Sousa, Thiagoharry, 9 edies annimas
Instrues do MIPS Fonte: http://pt.wikibooks.org/w/index.php?oldid=250818 Contribuidores: Kernelsafe, Master, Raylton P. Sousa, Thiagoharry, 5 edies annimas
Representao das Instrues Fonte: http://pt.wikibooks.org/w/index.php?oldid=199791 Contribuidores: Master, Raylton P. Sousa, Thiagoharry
As Pseudo-Instrues Fonte: http://pt.wikibooks.org/w/index.php?oldid=199786 Contribuidores: Master, Mike.lifeguard, Raylton P. Sousa, Thiagoharry, 1 edies annimas
Suporte Funes Fonte: http://pt.wikibooks.org/w/index.php?oldid=239421 Contribuidores: Master, Raylton P. Sousa, Thiagoharry, 3 edies annimas
Representao Numrica Fonte: http://pt.wikibooks.org/w/index.php?oldid=199790 Contribuidores: Master, Raylton P. Sousa, Thiagoharry, 3 edies annimas
As Operaes da Unidade Lgica Aritmtica Fonte: http://pt.wikibooks.org/w/index.php?oldid=199785 Contribuidores: Master, Raylton P. Sousa, Thiagoharry
Fontes, Licenas e Editores da Imagem
21
Fontes, Licenas e Editores da Imagem
Imagem:Cray-1-deutsches-museum.jpg Fonte: http://pt.wikibooks.org/w/index.php?title=Ficheiro:Cray-1-deutsches-museum.jpg Licena: Creative Commons Attribution 2.5 Contribuidores:
Clemens PFEIFFER
Imagem:Transistor_npn.png Fonte: http://pt.wikibooks.org/w/index.php?title=Ficheiro:Transistor_npn.png Licena: GNU Free Documentation License Contribuidores: Original uploader was
Pulsar at fr.wikipedia
Imagem:Logic-gate-index.png Fonte: http://pt.wikibooks.org/w/index.php?title=Ficheiro:Logic-gate-index.png Licena: GNU Free Documentation License Contribuidores: EugeneZelenko,
Ilmari Karonen, Jjbeard, Qvarie, Stefan506, The wub, Tothwolf, WikipediaMaster, 2 edies annimas
Imagem:ALU_Block_Diagram.png Fonte: http://pt.wikibooks.org/w/index.php?title=Ficheiro:ALU_Block_Diagram.png Licena: Creative Commons Attribution-Share Alike Contribuidores:
Tapani Taivalantti
Imagem: Kernel_Layout.svg Fonte: http://pt.wikibooks.org/w/index.php?title=Ficheiro:Kernel_Layout.svg Licena: Creative Commons Attribution-Sharealike 3.0 Contribuidores: Bobbo
Imagem:Toshiba_TC86R4400MC-200_9636YJA_top.jpg Fonte: http://pt.wikibooks.org/w/index.php?title=Ficheiro:Toshiba_TC86R4400MC-200_9636YJA_top.jpg Licena: GNU Free
Documentation License Contribuidores: EugeneZelenko, Morkork, Qurren, Sdrtirs, 3 edies annimas
Imagem:Circuito_soma.png Fonte: http://pt.wikibooks.org/w/index.php?title=Ficheiro:Circuito_soma.png Licena: GNU Free Documentation License Contribuidores: Thiagoharry
Imagem:Circuito_multiplicacao.png Fonte: http://pt.wikibooks.org/w/index.php?title=Ficheiro:Circuito_multiplicacao.png Licena: GNU Free Documentation License Contribuidores:
Thiagoharry
Imagem:Diagrama_circuito_multiplicacao.png Fonte: http://pt.wikibooks.org/w/index.php?title=Ficheiro:Diagrama_circuito_multiplicacao.png Licena: Creative Commons
Attribution-Sharealike 3.0 Contribuidores: Thiagoharry
Licena
22
Licena
Creative Commons Attribution-Share Alike 3.0
//creativecommons.org/licenses/by-sa/3.0/

Вам также может понравиться