MIPS
1 / 45
Este documento uma traduo adaptada do captulo "Introduction lassembleur MIPS" da sebenta "Cours de Compilation" de Jean-Christophe Filliatre (http://www.lri.fr/lliatr).
MIPS
2 / 45
Plano
1 2
MIPS
3 / 45
MIPS
4 / 45
De forma muitio resumida, um computador composto de: Uma unidade de clculo (CPU), contendo un pequeno numero de registos inteiros ou utuantes mecanismos de clculo de uma memria (RAM) composta de um grande nmero de bytes (8 bits) 33 por exemplo, 1Gb = 230 bytes = 233 bits, ou seja, 22 conguraes possveis da memria contm dados e programas (instrues)
MIPS
5 / 45
O acesso memria custa carro (tendo uma arquitectura capaz de realizar um bilio de instruo por segundo, a luz s consegue percorrer 30 centmetros entre cada instruo)
S. Melo de Sousa (DIUBI) MIPS 6 / 45
A realidade um pouco mais complexa... presena de vrios (co)processadores, alguns deles dedicados a operaes sobre utuantes uma ou vrias caches (polticas LRU, random etc..) virtualizao da memria (MMU) etc...
MIPS
7 / 45
Princpio de execuo
Esquematicamente, a execuo decorre da seguinte forma: um registo ($pc) contm o endereo da instruo por executar l-se os 4 (ou 8) bytes endereados por $pc (fase designada de fetch) interpretar estes bits como sendo instrues (fase designada de decode) executar a dita instruo (fase designada de execute) modica-se o registo $pc por forma a que este enderea a prxima instruo (a instruo seguinte, em geral, caso a instruo actual no obriga a um salto)
MIPS
8 / 45
Princpio de execuo
instruo: 000000 00001 00010 0000000000001010 descodicao: add $a1 $a2 10 i.e. juntar 10 ao registo $a1 e arquivar o resultado no registo $a2
S. Melo de Sousa (DIUBI) MIPS 9 / 45
Princpio de execuo
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 descodicada 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 ush do pipeline caso haja salto)
MIPS
10 / 45
Arquitectura MIPS
32 registos, r0 r31
r0 contm sempre 0 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 trs tipos de instrues:
instrues de transferncias, entre registos e/ou memria instrues de clculo instrues de salto
MIPS
11 / 45
SPIM
Na prtica , utilizaremos um simulador MIPS designado por SPIM Em linha de comando: spim [-file] file.s Em modo grco: xspim -file file.s (execuo passo a passo, visualizao dos registos, da memria, etc.)
MIPS
12 / 45
Instrues MIPS
Carregamento de uma constante (16 bits com signo) num registo li $a0, 42 lui $a0, 42 # a0 <- 42 # a0 <- 42 * 2^16
Cpia de um registo para outro move $a0, $a1 # cpia de *a1* para *a0*
MIPS
13 / 45
(aqui no h o equivalente com subi, muli, divi) negao neg $a0, $a1 valor absoluto abs $a0, $a1
S. Melo de Sousa (DIUBI)
# a0 <- -a1
# a0 <- |a1|
MIPS 14 / 45
Negao lgica (not 1001112 = 0110002 ) not $a0, $a1 # a0 <- not(a1)
Conjuno lgica (and (1001112 , 1010012 )= 1000012 ) and $a0, $a1, $a2 andi $a0, $a1, 0x3f # a0 <- and(a1,a2) # a0 <- and(a1,0...0111111)
Disjuno lgica (or (1001112 , 1010012 )= 1011112 ) and $a0, $a1, $a2 andi $a0, $a1, 42 # a0 <- or(a1,a2) # a0 <- or(a1,0...0101010)
MIPS
15 / 45
right shift aritmtico (cpia do bit do sinal) sra $a0, $a1, 2 # a0 <- a1 / 4
MIPS
16 / 45
ler uma palavra (32 bits) em memria lw $a0, 42($a1) # a0 <- mem[a1 + 42]
O endereo dado por um registo e um oset dado no formato 16 bits com sinal variantes para ler 8 ou 16 com sinal ou no (lb, lh, lbu, lhu).
MIPS
17 / 45
escrever uma palavra (32 bits) em memria sw $a0, 42($a1) # mem[a1 + 42] <- a0 #(cuidado com a ordem # dos parmetros)
O endereo dado por um registo e um oset dado no formato 16 bits com sinal variantes para ler 8 ou 16 (sb, sh).
MIPS
18 / 45
salto condicional beq $a0, $a1, label # se a0 = a1 salto para label # seno... nada
variantes: bne, blt, ble, bgt, bge (assim como comparaes sem sinal). variantes: (comparaes com zero) beqz, bnez, bltz, blez, bgtz, bgez.
MIPS
19 / 45
para um endereo arquivado num registo. jr $a0 para um endereo arquivado num registo, com arquivo do endereo da instruo seguinte num registo. jalr $a0, $a1 # salto para $a0, e arquivo da prxima # instruo em $a1
MIPS 20 / 45
possvel invocar alguns servios disponibilizados pela arquitectura de suporte (num simulador, so servios do sistema operativo subjacente). A instruo MIPS para esta chamada syscall. O cdigo da instruo por chamar deve estar no registo $v0, os argumentos em $a0 - $a3. O resultado ser colocado no registo $v0. Por exemplo, para usufruir dos servios da funo print_int basta: li $v0, 1 li $a0,42 syscall #cdigo de print_int #o valor (do universo) por mostrar
MIPS
21 / 45
Assembly MIPS
Como j sabem..... no costume programar em linguagem mquina, mas sim com recurso ao assembly. O assembly fornece certas facilidades: labels simblicos alocaes de dados globais pseudo-instrues
MIPS
22 / 45
Assembly MIPS
A directiva .text indica que instrues seguem. A directiva .data indica que dados seguem O cdigo car arquivado a partir do endereo 0x400000 e os dados caro arquivados a partir do endereo 0x10000000. Uma etiqueta simblica (label) introduzida por label: e o endereo que ela representa pode ser carregado num registo la $a0, label
MIPS 23 / 45
Hello world!
SPIM invoca o programa endereado por main e entrega-lhe o endereo onde recomear no m da sua execuo no registo $ra .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" ( .asciiz uma facilidade para .byte 104, 101, ... 0)
MIPS
24 / 45
Compilao e MIPS
O desao da compilao para o assembly (MIPS, em particular) conseguir traduzir um linguagem de alto nvel para este conjunto de instrues. Em particular, preciso: traduzir as estruturas de controlo (testes, ciclos, excepes, etc.) traduzir as chamadas s funes traduzir as estruturas de dados complexas (vectores, registos, objectos, fechos, etc.) alocar memria de forma dinmica
MIPS
25 / 45
Chamadas a funes
Facto: as chamadas a funes podem estar arbitrariamente aninhadas. Os registos podem no chegar para arquivar todos os parmetros, variveis locais e outros dados locais a cada chamada necessrio alocar memria para tal As funes procedem na base de uma poltica last-in rst-out, i.e. uma pilha.
MIPS
26 / 45
A pilha
A pilha posicionada na parte superior, e cresce no sentido dos endereos decrescentes. O registo $sp aponta para o topo da pilha. Os dados dinmicos (que sobrevivem s chamadas a funes) so alocadas na heap (eventualmente por um GC), na parte inferior da zona de dados, logo a seguir aos dados estticos. Assim temos casa arrumada...
MIPS
27 / 45
Chamadas a funes
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 car inutilizvel por f posteriormente. Existe vrias formas de resolver esta problemtica, mas de forma geral costuma-se respeitar uma conveno para chamadas
S. Melo de Sousa (DIUBI) MIPS 28 / 45
Chamada, em 4 etapas
Para o caller, mesmo antes da chamada Para o callee, logo a seguir chamada Para o callee, mesmo antes do m da chamada Para o caller, logo a seguir ao m da chamada
Estas organizam-se na base de um segmente de memria localizado no topo da pilha, designada de tabela de activao ou (em ingls) de stack frame, estando este situado entre $fp e $sp.
MIPS
30 / 45
Passa os argumentos em $a0 - $a3, e os restantes na pilha (se houver mais do que 4 argumentos) salvaguarda os registos $t0-$t9 que entende utilizar aps a chamada (na sua prpria tabela de activao ) executa: jal callee
MIPS
31 / 45
Alocar a sua tabela de activao, por exemplo: addi $sp, $sp, -28
Salvaguardar $fp e, a seguir, posicion-lo, por exemplo sw $fp, 24($sp) addi $fp, $sp, 24
salvaguardar $0 - $s7 e $ra caso seja necessrio $fp permite alcanar facilmente os argumentos e as variveis locais, com base num oset xo, qualquer que seja o estado da pilha.
3
MIPS
32 / 45
o callee, no m da chamada
1 2 3
coloca o resultado em $v0 (e em $v1 se for necessrio) restabelece os registos salvaguardados pop da sua tabela de activao, por exemplo addi $sp, $sp, 28
executa jr $ra
MIPS
33 / 45
pop dos eventuais argumentos 5, 6, etc.... (os que no couberam nos reguistos $a0 - $a3) restabelece os registos caller-saved.
MIPS
34 / 45
Plano
1 2
MIPS
35 / 45
MIPS em resumo
li $r0, C lui $r0, C move $r0, $r1 add addi sub div div mul neg slt slti sle seq sne $r0, $r0, $r0, $r0, $r1, $r0, $r0, $r0, $r0, $r0, $r0, $r0, $r1, $r1, $r1, $r1, $r2 $r1, $r1 $r1, $r1, $r1, $r1, $r1, $r C $r2 $r2 $r2 $r0 <- C $r0 <- 2^16*C $r0 <- $r1 $r0 $r0 $r0 $r0 $lo $r0 $r0 $r0 $r0 $r0 $r0 $r0 <<<<<<<<<<<<$r1 + $r1 + $r1 $r1 / $r1 / $r1 * -$r1 1 1 1 1 1 se se se se se $r2 C $r2 $r2 $r2, $hi <- $r1 mod $r2 $r2 (sem overflow)
<<<<<-
0 0 0 0 0
MIPS
36 / 45
MIPS em resumo
la lw sw beq beqz bgt bgtz $r0, adr $r0, adr $r0, adr $r0, $r0, $r0, $r0, $r1, label label $r1, label label $r0 <- adr $r0 <- mem[adr] mem[adr] <- $r0 salto salto salto salto se se se se $r0 $r0 $r0 $r0 = = > > $r1 0 $r1 0
beqzal $r0, label bgtzal $r0, label j jal jr jalr label label $r0 $r0
salto se $r0 = 0, $ra <- $pc + 1 salto se $r0 > 0, $ra <- $pc + 1 salto salto salto salto
MIPS
label label, $ra <- $pc + 1 $r0 $r0, $ra <- $pc + 1
37 / 45
MIPS em resumo
Registers Calling Convention Name Number Use Callee must preserve? $zero $0 constant 0 N/A $at $1 assembler temporary No $v0-$v1 $2-$3 values for function returns and expression evaluation No $a0-$a3 $4-$7 function arguments No $t0-$t7 $8-$15 temporaries No $s0-$s7 $16-$23 saved temporaries Yes $t8-$t9 $24-$25 temporaries No $k0-$k1 $26-$27 reserved for OS kernel N/A $gp $28 global pointer Yes $sp $29 stack pointer Yes $fp $30 frame pointer Yes $ra $31 return address N/A
S. Melo de Sousa (DIUBI) MIPS 38 / 45
endereo em $v0
MIPS
39 / 45
41 / 45
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. Funes de arquivo e de carregamento na pilha:
l e t p u s h r r = sub $sp , $sp , 4 sw r , 0 ( $ s p ) l e t p o p r r = lw r , 0 ( $ s p ) | add $sp , $sp , 4 |
MIPS
43 / 45
MIPS
44 / 45
MIPS
45 / 45