Beruflich Dokumente
Kultur Dokumente
Aqui tambm, a realidade bem mais complexa do que este ltimo, muito
simples, exemplo.
Pipelines: vrias instrues so executadas em paralelo (por exemplo, numa
sequncia de 3 instrues, enquanto que a primeira executada, a segunda
j descodificada e a terceira carregada, isso tudo num s ciclo CPU - i.e.
em simultneo)
Branch prediction. Para optimizar o pipelining, existe a possibilidade de
adivinhar (com base em determinadas heursticas) o resultado de instrues
de salto (que necessitam fazer um flush do pipeline caso haja salto)
32 registos, r0 r31
I r0 contm sempre 0
I Estes registos podem ser referenciados por outros nomes
(correspondentes a uma conveno de nomes admitida nos simuladores
que vamos usar):
zero, at, v0-v1, a0-a3, t0-t9, s0-s7, k0-k1, gp, sp, fp, ra
I trs tipos de instrues:
F instrues de transferncias, entre registos e/ou memria
F instrues de clculo
F instrues de salto
li $a0, 42 # a0 <- 42
lui $a0, 42 # a0 <- 42 * 2^16
valor absoluto
Rotao
salto condicional
variantes: bne, blt, ble, bgt, bge (assim como comparaes sem
sinal).
variantes: (comparaes com zero) beqz, bnez, bltz, blez, bgtz,
bgez.
j label
jr $a0
.text
.data
label:
la $a0, label
.text
main: li $v0, 4 # cdigo de print_int
la $a0, hw # endereo da string
syscall # chamada ao sistema
jr $ra # fin do programa
.data
hw: .asciiz "hello world\n"
As funes procedem na base de uma poltica last-in first-out, i.e. uma pilha.
Quando uma funo f (quem invoca, ou caller) pretende invocar uma funo g
(que chamado ou callee), f executa:
jal g
quando a funo invocada termina, esta devolve o controlo para o caller, com:
jr $ra
Mas ento:
se g ela prpria invoca uma funo, o registo $ra ser actualizado (e perder
o valor de que chamou g )
da mesma forma, qualquer registo utilizado por g ficar inutilizvel por f
posteriormente.
Existe vrias formas de resolver esta problemtica, mas de forma geral costuma-se
respeitar uma conveno para chamadas
jal callee
sw $fp, 24($sp)
addi $fp, $sp, 24
3 salvaguardar $0 - $s7 e $ra caso seja
necessrio
$fp permite alcanar facilmente os argumentos e as variveis locais, com base
num offset fixo, qualquer que seja o estado da pilha.
jr $ra
slt $r0, $r1, $r2 $r0 <- 1 se $r1 < $r2, $r0 <- 0 seno
slti $r0, $r1, C $r0 <- 1 se $r1 < C, $r0 <- 0 seno
sle $r0, $r1, $r2 $r0 <- 1 se $r1 <= $r2, $r0 <- 0 seno
seq $r0, $r1, $r2 $r0 <- 1 se $r1 = $r2, $r0 <- 0 seno
sne $r0, $r1, $r2 $r0 <- 1 se $r1 <> $r2, $r0 <- 0 seno
bgt $a0,1,notOne
move $v0,$a0 # fib(0)=0, fib(1)=1
b fret # if n<=1
S. Melo de Sousa (DIUBI) MIPS 41 / 45
MIPS - um exemplo : Fib
# data segment
.data
endl: .asciiz "\n"
Um registo $sp (stack pointer) que aponta para a primeira clula livre da
pilha
O endereamento faz-se com base em bytes: uma palavra de 32 bits cabe
em 4 bytes.
l e t p o p r r = lw r , 0 ( $ s p ) |
add $sp , $sp , 4