TD N°1
« Les jeux d’instructions MIPS»
Exercice 1 :
a/
addu $t0, $s1, $s2 # $t0 = g + h
addu $t1, $s3, $s4 # $t1 = i + j
subu $s0, $t0, $t1 # f = (g+h)–(i+j)
b/
c/
Exercice 2
a/ if (a == b) c = d + e; else c = d – e;
Avec a, b, c, d, e sont respectivement $s0, …, $s4
bne $s0, $s1, else
addu $s2, $s3, $s4
j exit
else: subu $s2, $s3, $s4
exit: . . .
b/ if (($s1 > 0) && ($s2 < 0)) {$s3++;};
bgtz $s1, L1 # first expression
j next # skip if false
L1: bltz $s2, L2 # second expression
j next # skip if false
L2: addiu $s3,$s3,1 # both are true
next:
ou
blez $s1, next # skip if false
bgez $s2, next # skip if false
addiu $s3,$s3,1 # both are true
next:
c/ if (($sl > $s2) || ($s2 > $s3)) {$s4 = 1;};
bgt $s1, $s2, L1 # yes, execute if part
ble $s2, $s3, next # no: skip if part
L1: li $s4, 1 # set $s4 to 1
next:
d/ if( $s1 <= $s2 ) {$s3 = $s4}; avec $s1 et $s2 sont non signés
bgtu $s1, $s2, next
move $s3, $s4
next:
e/ if (($s3 <= $s4) && ($s4 > $s5)) {$s3 = $s4 + $s5}; avec $s3, $s4, et $s5 sont singés
bgt $s3, $s4, next
ble $s4, $s5, next
addu $s3, $s4, $s5
next:
f/ i = 0; do {target[i]=source[i]; i++;} while (source[i]!=0);
avec Adresse de source dans $s0 et l'adresse de la cible dans $s1 Les chaînes sont terminées par un caractère nul
move $t0, $s0 # $t0 = pointer to source
move $t1, $s1 # $t1 = pointer to target
L1: lb $t2, 0($t0) # load byte into $t2
Publicité
sb $t2, 0($t1) # store byte into target
addiu $t0, $t0, 1 # increment source pointer
addiu $t1, $t1, 1 # increment target pointer
bne $t2, $zero, L1 # loop until NULL char
g/ sum = 0; for (i=0; i<n; i++) sum = sum + A[i];
avec $s0 = addresse de tableau A, $s1 = longueur de tableau A= n
move $t0, $s0 # $t0 = address A[i]
xor $t1, $t1, $t1 # $t1 = i = 0
xor $s2, $s2, $s2 # $s2 = sum = 0
L1: lw $t2, 0($t0) # $t2 = A[i]
addu $s2, $s2, $t2 # sum = sum + A[i]
addiu $t0, $t0, 4 # point to next A[i]
addiu $t1, $t1, 1 # i++
bne $t1, $s1, L1 # loop if (i != n)
Exercice 3
Ecrire un programme SPIM qui permet de recopier les éléments d’une table source Tab1 dans une table destination Tab2 en ordre inverse et faire la somme des éléments de cette dernière table et mettre le résultat dans la case mémoire Somm avec affichage sur écran de ce résultat
Soit la déclaration suivante :
.data
tab1 : .word 10,20,30,40,50
tab2 : .word 0,0,0,0,0
somme: .word 0
.text
main: li $v1,0
li $s1,5
li $s2,4
la $t0,tab1
la $t1,tab2+16
la $t2,somme
boucle: lw $s0,0($t0)
sw $s0,0($t1)
add $t0, $s2,$t0
sub $t1,$t1,4
sub $s1,$s1,1
add $v1,$s0,$v1
sw $v1,0($t2)
bne $s1,$zero,boucle
li $v0,1
move $a0,$v1
syscall
li $v0 10
syscall
Exercice 4
Ecrire un programme SPIM qui permet sélectionner les éléments d’une table source Tab1 en nombres paires et impaires et de les ranger respectivement dans deux tables Tabpaire et Tabimpaire.
.data
tab1 : .word 1,2,3,4,5,6
tabpaire : .word 0,0,0,0,0
tabimpaire : .word 0,0,0,0,0
.text
Publicité
main: li $s2,6
la $t0,tab1
la $t1,tabpaire
la $t2,tabimpaire
boucle: lw $s0,0($t0)
andi $s1,$s0,1
beq $s1,$zero,paire
sw $s0,0($t2)
add $t2,$t2,4
j next
paire: sw $s0,0($t1)
add $t1,$t1,4
next: add $t0,$t0,4
sub $s2,$s2,1
bne $s2,$zero,boucle
li $v0,10
syscall
Exercice 5
Ecrire un procédure trouve\_b qui cherche le lettre b dans une chaine de caractère et retourne la position de b dans $2 sinon retourne les nombres des caractères dans la chaine.
.data
lch1:.word0x07
ch1:.asciiz"acgfvbh"
.text
main: lw $a1,lch1
lw $a2,'b'
jal trouve\_b
move $s0,$v0
li $v0,1
move $a0,$v1
syscall
li $v0,10
syscall
trouve\_b: li $v0,0
li $t0,0
loop: bge $t0,$a1,exit
add $t1,$a0,$t0
lb $t2,0($t1)
bne $t2,$a2,num
add $t0,$t0,1
exit: move $v0,$t0
jr $ra
num: add $t0,$t0,1
j loop
Exercice 6
.data
str1: .asciiz "Entrez un entier :"
str2: .asciiz "La factorielle est "
.text
Publicité
main: li $v0, 4 # system call code for print\_str
la $a0, str1 # address of string to print
syscall # print the string
li $v0, 5 # system call code for read\_int
syscall # read int, result in $v0
move $a0,$v0 # prepare parameter for calling fact
jal fact # call fact, on return the result is in $3
sortie: li $v0, 4 # system call code for print\_str
la $a0, str2 # address of string to print
syscall # print the string
li $v0, 1 # system call code for print\_int
move $a0, $3 # integer to print
syscall # print the integer
li $v0, 10 # on sort proprement du programme
syscall #
fact: bgt $a0, 1, recur # si le parametre est > 0, appel recursif, sinon retourne 1
li $3, 1 # fact(0) = 1
j $ra # retourne (adresse de retour dans $ra)
recur: sub $sp, $sp, 8 # place pour sauver l’adresse de retour ET le parametre
sw $ra, ($sp) # sauve adresse de retour
sw $a0, 4($sp) # sauve le parametre
sub $a0, $a0, 1 # n-1
jal fact # appel recursif, le resultat est dans $3
lw $a0, 4($sp) # restaure le parametre
mul $3, $a0, $3 # multiplie par le parametre
lw $ra, ($sp) # restaure adresse de retour
add $sp, $sp, 8 # libere place pour l’adresse de retour
j $ra # retourne (adresse de retour dans $ra)
Exercice 7
fib: subi $sp,$sp,12 # save registers on stack
sw $a0, 0($sp) # save $a0 = n
sw $s0, 4($sp) # save $s0
sw $ra, 8($sp) # save return address $ra
bgt $a0,1, gen # if n>1 then goto generic case
move $v0,$a0 # output = input if n=0 or n=1
j rreg # goto restore registers
gen: subi $a0,$a0,1 # param = n-1
jal fib # compute fib(n-1)
move $s0,$v0 # save fib(n-1)
sub $a0,$a0,1 # set param to n-2
jal fib # and make recursive call
add $v0, $v0, $s0 # $v0 = fib(n-2)+fib(n-1)
rreg: lw $a0, 0($sp) # restore registers from stack
lw $s0, 4($sp) #
lw $ra, 8($sp) #
addi $sp, $sp, 12 # decrease the stack size
jr $ra