next up previous
Next: Examen finalGroupe 10, Up: No Title Previous: Examen finalGroupe 11,

Examen final, Groupe 40, Automne 1995

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


next up previous
Next: Examen finalGroupe 10, Up: No Title Previous: Examen finalGroupe 11,

Mario Latendresse
Wed Jan 15 18:27:16 EST 1997