Philippe Giabbanelli Notes sur l’assembleur MIPS
3
# the goal of the program is to add 2 + 3 and print “5 oranges”
.text
.globl __start
__start:
lw $t0, mynum # t0 ← 2 (mynum)
li $t1, 3 # t1 ← 3
add $a0, $t0, $t1 # a0 ← mynum + 3
li $v0, 1 # ready to print an int
syscall # ask the OS to run service 1
la $a0, str # load the address of str
li $v0, 4 # ready to print a string
syscall # print the string
li $v0, 10 # ready to end
syscall # exit
.data
mynum: .word 2 # a word is 32 bits. mynum is a label
str: .asciiz “oranges\n” # asciiz ends the string with \0
Avec ‘mul Rdest, Rsrc1, src2’, on fait une multiplication de nombres signés et on stocke le résultat sur 32
bits. Or, multiplier 32 bits par 32 bits peut donner un résultat sur 64 bits, et alors ça ne loge pas, il y a une
arithmetic overflow. La pseudo-instruction mulo regarde s’il y a overflow, et arrête proprement la chose ;
c’est implémenté par plusieurs instructions, pour disposer de la vérification.
L’instruction div marche de même manière que mul :
li $t0, 20
div $a0, $t0, 3
li $v0, 1
syscall # affiche 6, à savoir le résultat de la division entière
Avec rem Rdest, Rsrc1, src2 on obtient le reste (remainder) de la division. Il y a aussi une version non-
signée de la multiplication et de la division, en mettant un ‘u’ à la fin (exemple : mulou).
L’instruction réelle de la machine pour la multiplication est mult Rsrc1, Rsrc2. Comme le résultat fait 64
bits, il est stocké dans deux registres :
En contrôlant l’allure de hi et de lo, on sait s’il y a eu overflow ou non. C’est le même principe avec la
division, où on met le quotient en lo et le reste en hi.
Optimisation
(compilateur)
expansion
S’ajoutent aux
32 registres de
l’ordinateur
Register lo Register hi
Il y a des pseudo-instructions qui
sont ensuite expansées, comme
neg $t3, $t0 → sub $t0, $0, $t0
Où $0 contient toujours 0.
La forme normale est :
<add|sub> Rdest, Rsrc1, src2
Où src2 est un registre ou une
constante. Parfois, addi est utilisé
pour la forme à 2 registres et une
constante. Il y aussi un raccourci :
add $t0, 1 → add $t0, $t0, 1
Cela marche de la même manière
avec la soustraction, mais il n’y a
pas de subi. C’est plutôt :
addi $t5, $t0, -5
sub $t5, $t5, 4 ≡ addi $t5, $t5, -4
lw $t0, apples
div $t1, $t0, 8 # apples / student
rem $t2, $t0, 8 # remainder
li $1, 8
div $t0, $1
mflo $t1
li $1, 8
div $t0, $1
mfhi $t2
li $1, 8
div $t1, $1
mflo $t2
mflo $t3