Examen Final
Inf 2170, Groupe 40
Automne 1995, 25 points
Durée: 3h
À livre ouvert
4 pts No 1) Le registre d0.l
contient deux
nombres entiers, codés en complément à deux, dont le premier x
s'étend du bit 0 au bit 19 et le second y du bit 20 au bit
31. Donnez une séquence d'au plus 10 instructions MC68K pour
additionner y à x. Le résultat x+y tient dans les bits 0 à 19 de
d0.l
avec y dans les bits 20 à 31. ( On ne se préoccupe pas
de débordement. Portez attention aux nombres négatifs.)
Solution
move.l d0,d1 ; prendre une copie de y,x move.w #20,d2 ; pour le décalage qui suit asr.l d2,d1 ; enlever x en gardant le signe de y add.l d1,d0 ; additionner y à x andi.l #$fffff,d0 ; garder seulement les bits 0 à 19 lsl.l d2,d1 ; remettre y dans les bits 20 à 31 or.l d1,d0 ; coler y dans d0.l
5 pts No 2) Soit une codification à virgule-fixe avec 20 bits pour la partie entière et 12 bits pour la partie fractionnaire ([20,12]).
pts a) Donnez la plus grande valeur et la plus petite valeur représentable dans cette codification. Montrez vos calculs.
3 pts b) Indiquez comment faire une multiplication de deux nombres [20,12] en assembleur MC68K qui donne un résultat en virgule-fixe [20,12].
En se basant sur votre code, est-ce qu'il y a un débordement possible? Pourquoi?
En se basant sur votre code, est-ce qu'il y a une perte de précision possible? Pourquoi?
Solution a)
Plus grande valeur: 524287.99975
Calcul: Il s'agit du nombre binaire
01111111111111111111.111111111111
, qui vaut
Plus petite valeur (différent de 0): 0.00024
Calcul: 3 Il s'agit du nombre binaire 0.000000000001, qui vaut .
b) Voici deux solutions possibles.
; ; Le premier nombre [20,12] est dans d0.l et le deuxième nombre ; [20,12] est dans d1.l. ; Le résultat de la multiplication est dans d1.l ; muls.l d0,d2:d1 ; résultat sur 64 bits move.w #12,d3 ; fait un décalage de 12 bits lsr.l d3,d1 ror.l d3,d2 andi.l #$fff00000,d2 or.l d2,d1 ; une instruction de trop !
Deuxième solution plus courte mais moins performante à cause de
l'instruction divs.l
.
; ; Le premier nombre [20,12] est dans d0.l et le deuxième nombre ; [20,12] est dans d1.l. ; Le résultat de la multiplication est dans d1.l ; muls.l d0,d2:d1 ; résultat sur 64 bits divs.l #4096,d2:d1 ; décalage de 12 bits (plutôt coûteux)
Il y a potentiellement un débordement, car le passage de 64 bits à 32 bits peut perdre des bits significatifs de la partie haute.
Il y a potentiellement une perte de précision, car le décalage de 12 bits pour le passage de 64 bits à 32 bits peut faire sortir des bits significatifs de la partie basse.
5 pts No 3) Soit une matrice M
de 50 lignes
et 20 colonnes de nombres entiers de 32 bits définie dans la partie
data
. (Le premier élément est M[0,0] et la matrice est stockée
ligne par ligne en mémoire.). Donnez une séquence d'au plus 15
instructions assembleur MC68K pour sommer tous les nombres des
colonnes 12, 16, 18 et 19. Le résultat se retrouve dans le registre
d0.l
. (Il n'est pas nécessaire de se préoccuper de
débordement.)
Solution
lea M+12*4,a0 ; a0 pointe l'entier M[0,12] clr.l d0 ; somme à zéro move.w #49,d1 ; 50 lignes lignes: add.l (a0),d0 ; colonne 12 add.l (4*4,a0),d0 ; colonne 16 add.l (6*4,a0),d0 ; colonne 18 add.l (7*4,a0),d0 ; colonne 19 lea (20*4,a0),a0 ; passe à la ligne suivante dbra d1,lignes
5 pts No 4) Écrire une sous-routine qui accepte en entrée une matrice de 25 lignes et 35 colonnes d'entiers de 16 bits et un pointeur vers une zone de (25*35*4) octets. La sous-routine retourne une copie de la matrice, dans la zone, mais dont les entiers sont étendus sur 32 bits. Votre solution a au plus 20 instructions.
Solution
; Entrée: a0 pointe une matrice M de 25 lignes et 35 colonnes d'entiers ; de 16 bits ; a1 pointe une zone de 25*35*4 = 3500 octets ; Sortie: a1 pointe une copie dans la zone de M dont les entiers ; sont étendus sur 32 bits ; CopieEtendue: movem.l a0-a1/d0-d1,-(sp) move.w #25*35-1,d0 prchEntier: move.w (a0)+,d1 ext.l d1 move.l d1,(a1)+ dbra d0,prchEntier movem.l (sp)+,a0-a1/d0-d1 rts
6 pts No 5) Un écran graphique est formé de pixels à
1024 couleurs. Chaque pixel utilise donc 10 bits. L'écran a 512
colonnes et 400 lignes et les pixels sont stockés de façon compacte,
c'est-à-dire avec aucune perte de bits. Le premier pixel occupe les
bits 0 à 7 du premier octet et les bits 0 à 1 du deuxième octet, le
deuxième pixel les bits 2 à 7 du deuxième octet et les bits 0 à 3 du
troisième octet, etc. Supposons que le registre d0.w
contient
le numéro de ligne et le registre d1.w
le numéro de colonne du
pixel à modifier. Écrire une séquence d'instructions MC68K pour placer ce
pixel à la couleur `102'. L'écran débute à l'adresse stockée dans
a0
. Votre solution a au plus 20 instructions.
SolutionOn calcul (512x+y)10, où x est le numéro de ligne et y le numéro de colonne, qui est le numéro du premier bit du pixel à modifier. Soit n cette valeur. Pour accéder aux 10 bits de ce pixel il faut avoir l'adresse en octet, par rapport au début de l'écran, qui est la valeur . L'octet adjacent contient une partie des 10 bits, il faut donc charger le mot à cette adresse. Le reste de la division par 8 est le nombre de bits à sauter au début du mot. Il ne faut oublier d'inverser les octets pour voir les bits dans le bon sens.
mulu.w #512,d0 ; résultat sur 32 bits ext.l d1 ; numéro de colonne sur 32 bits add.l d1,d0 ; d0.l contient indice du pixel mulu.l #10,d0 ; d0.l contient l'indice du premier bit, n divul.l #8,d1:d0 ; d0.l contient l'indice de l'octet move.w (a0,d0.l),d2 ; charger les 2 octets contenant les 10 bits addi.w #8,d1 ; plus 8 à cause de l'inversion des octets move.w #$fc00,d4 ; préparer un masque pour mettre les 10 bits à 0 rol.w d1,d4 ; aligner les 10 bits and.w d4,d2 ; mettre les 10 bits à 0 move.w #102,d3 ; rol.w d1,d3 ; aligner la valeur 102 avec les 10 bits or.w d3,d2 ; mettre la valeur 102 dans le pixel move.w d2,(a0,d0.l) ; replacer le mot avec la nouvelle couleur