Vous êtes sur la page 1sur 51

CEG3536 – Architecture d’ordinateurs II

CEG3536 – Architecture d’ordinateur II

Professeur: Mohamed Ali Ibrahim, ing., Ph.D.

Module 5 – Le développement de logiciel

1
Source: Notes du cours du professeur Gilbert Arbez
Sujets de discussion
◼ Le processus du développement de logiciel
◼ Conception
◼ Codage
 Échange de paramètres
 Code structuré

◼ Le débogage du programme
◼ Lecture: Cady, Chapitre 3, 8 et 9, Conception
Tic-Tac-Toe

2
Le processus du développement de logiciel
◼ Définition de problème: Identifier ce qui devrait être fait
◼ Conception: conception structurée des modules et algorithmes
 Un algorithme exprime les étapes détaillées (mais pas chaque instruction
machine)
 Ex: Charger la variable varA avec le contenu pointé par pointeur ptr
varA ← [ptr] (pseudo-code) varA = *ptr; (lang. prog. C)
◼ varA et ptr peuvent être des registres ou emplacements de mémoire
 Allons utiliser le C pour concevoir les programmes assembleurs
◼ Programmation: la conversion de la conception à un programme
◼ Test du programme
 Test de module
 Test du système
◼ L’entretien du programme
◼ La documentation

3
Spécification des besoins
◼ Bien comprendre le problème
◼ Besoin de savoir ce qui doit être fait
◼ Bonne communication avec le client est
essentielle
◼ Jeu Tic-Tac-Toe
◼ Règles du jeu
 Matrice de 3 X 3
 Chaque joueur à son tour pour placer X ou O dans la
matrice
 Un joueur gagne quand trois X ou trois O sont en
ligne et adjacent (horizontal, vertical, diagonal)
 Quand la matrice est pleine pas de gagnant,
4
Conception descendante (top-down)

◼ Conception en niveaux
◼ L’attention se tourne vers la solution du problème
◼ Le problème est divisé
 Définitde plus petites tâches
 Petites tâches peuvent encore être subdivisées
 Dans de grands projets, les tâches sont partagées parmi plusieurs
membres d’une équipe

5
La conception du
Gameboy Tic-Tac-Toe
Tic-Tac-Toe
Gameboy

Display Module Play Module Test Win Module

Debug12

6
Plus au sujet de la conception descendante
◼ Doit assurer que les niveaux soient corrects
 Besoin de plusieurs passes
◼ Reporter les détails
 Travail progressivement sur plus de détails aux niveaux inférieures
◼ Raffine la conception de façon successive
 À mesure que les niveaux inférieurs, des changements sont apportés aux
niveaux supérieurs
◼ Concevoir des algorithmes
 Porte l’attention d’abords aux algorithmes pour résoudre les problèmes,
sans se soucier des détails de la programmation
 Utiliser un pseudo code ou un organigramme
 Dans notre cas, nous allons utiliser un langage haut-niveau (C) comme
pseudocode pour représenter nos algorithmes des programmes
assembleurs.

7
Conception ascendante (bottom-up)
◼ Codage avant que la conception soit complétée
 Ne respecte pas le report de détails
 Peut rendre plus difficile la conception des niveaux supérieures
 Viole le raffinement successif
 Difficile d’optimiser les niveaux inférieurs basées sur les décisions faîtes
aux niveaux supérieurs
◼ Offre des avantages
 L’utilisation d’outils génériques du code offre des fonctions générales
(Utilisation du Debug-12)

8
Approche pratique
◼ Difficile de suivre les idéaux de la conception
descendante
 Utilise du code déjà disponible
 Les contraintes imposées par les fonctions sont compensées par
le temps sauvé du développement du code
◼ Approche pratique
 Faire avancer la conception le plus possible avant de coder
 Utiliser le code déjà développé et tester lorsque c’est possible
◼ Développement itératif
 Cycles besoins-conception-codage-testing pour développement
d’un système de façon itérative
 Commencer avec les fonctions critiques
 Développement évolutionnaire

9
Outils de conception
◼ Programmation structurée
 L’utilisationde structures de base: séquence,
décision et répétition
◼ Minimise l’interaction et l’interconnexion entres éléments d’un
programme
 Éviter les GOTO’s (ceci est très facile avec la
programmation assembleur)
 Garder les segments de programmes petits – plus
facile à gérer
 Organisation hiérarchique de la solution au problème
 Une entrée et une sortie

10
Séquence d’instructions
◼ Programme C:
byte qu; // quotient de la division
byte rem; // restant de la division
qu = num/10;
rem = num%10;
*addr = qu + ASCII_CONV_NUM;
*(addr+1) = rem + ASCII_CONV_NUM;

• Notez que seulement des noms de variables sont


utilisées dans les expressions.
• Ceci garde le « pseudo-code » indépendant de l’UCT ou
MCU utilisé
11
If-Then-Else
if(winch == 'O')
{
oscr++;
doneMsg = OWMSG;
}
else
{
xscr++;
doneMsg = XWMSG;
}
12
If-Then
offset = *offsetPtr++;
if(offset == 0) // end of offsetArray?
{
retval = isDraw();
break;
}

13
If-ElseIf
sum = *ptr;
sum = sum + *(ptr+ofst2);
sum = sum + *(ptr+2*ofst2);
if(sum == (byte)XWINSUM)
retval = 'X‘
else if(sum == OWINSUM)
retval = 'O';
else
retval = SPACE;
14
While-Do
int count=9; // compteur
byte *ptr = (byte *) gamePlay;
while(count != 0)
{
*ptr++ = SPACE; // stocker espace
count--;
}

15
Do-While
int count=9; // compteur
byte *ptr = (byte *) gamePlay;
do
{
*ptr++ = SPACE; // stocker espace
count--;
} while(count != 0);

16
Do-While-Break
ptr = &gamePlay[0];
retval = '-';
cnt = 9;
do
{
if(*ptr++ == SPACE)
{
retval = SPACE;
break;
}
cnt--;
} while(cnt != 0);
◼ Attention – utilisez au minimum le break.
◼ Seulement pour simplifier la logique quand l’expression logique
du while ne suffit pas!!
17
Sous-programmes – fonctions C
◼ Définir les fonctions
 Déclaration de la fonction
<type> nomFonction( <listes paramètres> )
{
// instructions
}
 <type> peut être un type simple ou pointeur (adresse à un type
simple, tableau ou structure).
 <listes paramètres>: déclarations de variables pour recevoir
arguments (valeurs)
 Ex: int strlen(char *chaine) { … }
 En assembleur, il serait possible de retourner plusieurs valeurs,
donc le C nous limite
◼ Utilisez seulement un point de sortie: une seule
instruction return à la fin de la fonction
◼ Appel de fonction
 Ex: nbr = strlen(“Une chaine”);
18
Exemples
◼ Module GameBoy Tic-Tac-Toe
 Programme principal
◼ Module Game Display
 Sous-programme showbrd

19
L’Utilisation de modules
◼ Conception descendante mène à des programmes qui peuvent
être écrits en modules
 Un membre d’équipe peut être responsable du développement d’un
module (Exemple – le module “Clavier” du lab 2).
 Objectif – tenter de créer des modules indépendants
 Trois attributs: fonction, liens avec les autres modules, sa logique.

20
Attributs de module
◼ Fonction:
 Décrit ce que fait le module.
 Certain contient une collection de fonctions sans relations, par
exemple un module utilitaire
 D’autres offres des fonctions avec une relation logique, par
exemple, le module “Games Display Module”
 Encore d’autre offre une simple fonction, par exemple les
modules “Test Win Module” et “Play Module””
◼ Liens entre modules
 Modules interagissent entre eux
 Défi: le plus possible garder les modules indépendants
 Par exemple, utiliser des variables locales au lieu de globales
◼ La logique du module
 Comment le module complète sa tâche

21
Échange de paramètres
◼ Les données sont
échangées entre un
sous-programme et le
code appelant
 Données sont envoyées
vers le sous-
programme
 Données sont
retournées par le sous-
programme
◼ Plusieurs approches
sont utilisées dans
l’échange de données

22
Techniques pour l’échange de
paramètres
◼ Avec les registres
 Rapide et efficace
 Général (n’affecte pas la mémoire)
 Exemple: printf utilise le registre D
 Mais seulement quelques registres
disponibles
◼ Les bits de code d’états
 Bits de code d’état (par exemple le bit report)
peut être utilisé pour retourner une valeur
Booléenne
23
Techniques pour l’échange de
paramètres
Mémoire globale
 Accessible par toutes parties du programme
 Difficile de trouver le code qui cause un bogue
 Accroît les liens entre modules
 L’échange d’adresses de variables commun
 Exemple: le “game matrix array”
◼ L’utilisation de la pile
 Puissant et général
 La pile sert aussi pour les variables locales
 Attention aux opérations balancées
 Utilisez une bonne documentation

24
L’utilisation de la pile avec les sous-
programmes ◼ Contenu de la pile
 Arguments pour le sous-
SP programme (peut aussi
retourner les valeurs)
Local Variables  Adresse de retour (placé
sur la pile par BSR/JSR)
 Contenu de registres
Preserved sauvés (pour préserver
registers valeurs)
 Espace pour variables
Return address locales
Subroutine  Lorsque le RTS est
exécuté, le SP doit
arguments pointer à l’adresse de
retour

25
Traduction des invocations de fonction C
◼ Une invocation de fonction C demande l’échange des
données suivantes:
 0 ou plusieurs arguments (valeurs, maximum 16 bits)
 Une valeur de retour (maximum 16 bits)
 Arguments et valeur de retour se limite au suivant: type simple (8
bits ou 16 bits), pointeur (à un tableau ou structure)
◼ Arguments sont placés sur la pile et dans le registre D
 Un seul argument – dans le registre D
 Deux ou plusieurs arguments –
◼ Empile les arguments sur la pile à partir de l’argument à la droite
dans liste d’arguments
◼ Argument la plus à gauche est placé dans le registre D
◼ Valeur de retour se place dans le registre D.
◼ Variables locales de fonctions sont placées soit sur la
pile, soit dans un registre
26
Normes pour le codage assembleur
◼ Style pour la création du code source
 Adopter un format pour le code
◼ Éléments du programme
 En-tête du programme
 EQU d’assembleurs (définition de constantes)
 Programme principal
◼ Emplacement
◼ Initialisation
◼ Code principale
◼ Fin de programme
 Modules – collection de sous-programmes
◼ Placer dans des fichiers différents
 Définitions des données constantes
 Données variables
◼ Emplacement
◼ Allocation
 Sections – pour appuyer la liaison de modules
27
En-tête de programme
Program Element Program Example
Program Header ; MC68HC12 Assembler Example
;
; This program is to demonstrate a
; readable programming style.
; It counts the number of characters
; in a buffer and stores the result in
; a data location. It then prints
; the number of characters using
; D-Bug12 Monitor routines.
; Source File: M6812EX1.ASM
; Author: F. M. Cady
; Created: 5/15/97
; Modifications: None

28
EQU d’assembleur
Program Element Program Example
System Equates. ; Monitor Equates
out2hex:EQU $FE16 ; Output 2 hex nibbles
putchar:EQU $FE04 ; Print a character
; I/O Ports
PORTH: EQU $24 ; Port H address
PORTJ: EQU $28 ; Port J address
Constant Equates ; Constant Equates
CR: EQU $0d ; CR code
LF: EQU $0a ; LF code
NULL: EQU $00 ; End of ASCII string
NIL: EQU 0 ; Initial data value
Memory Map ; Memory Map Equates
Equates PROG: EQU $4000 ; Locate the program
DATA: EQU $6000 ; Variable data areas
STACK: EQU $8000 ; Top of stack
29
Programme principal
◼ Emplacement
 La directive ORG pour placer le code en mémoire
◼ Initialisation
 La pile
 Variables globales

◼ Code principal
 Algorithme du premier niveau
◼ Fin de programme
 Par exemple, SWI
30
Sous-programmes
; Subroutine - updateRow(ptr,rptr) – Display Module
; Parameters: ptr - pointer to game matrix array (in D)
; rptr - pointer to a row (on stack PBL_RPTR)
; Returns: nothing
; Variables: none

; Stack Usage
OFFSET 0 ; to setup offsets into stack
PBL_PR_Y DS.W 1 ; preserve Y - used as rptr
PBL_PR_X DS.W 1 ; preserve X - used as ptr
PBL_RA DS.W 1 ; return address
PBL_RPTR DS.W 1 ; rptr

◼ Dessinez un diagramme qui montre le contenu de la pile?


◼ Où placeriez-vous une variable locale, disons cmpte, sur la pile?

31
Exemple
◼ Dessinez le cadre de la pile pour le segment du
programme, après la dernière leas -10,sp est
exécuté:

pshy

32
Solution

33
Appel par valeur (CALL-BY-VALUE)
Opération :
◼ Avant de donner le contrôle au sous-
programme (SUB), MAIN place les données
dans les registres (A, B, X, Y) ou dans la
mémoire, puis JSR SUB est exécutée.

◼ SUB traite les données et avant de rendre le


contrôle à MAIN, SUB place les résultats dans
les registres de microprocesseur ou la
mémoire et puis exécute RTS

34
* CALL-BY-VALUE: the SUM OF SQUARES PROGRAM squares all
the numbers of addresses $4080 to $40FF and puts the sum of
the squares as a 16-bit result in X.
; ----------------------- Start MAIN -----------------------
ORG $4000 ;start address
LDX #0 ;init sum S = 0
LDY #$4080 ;init. data block pointer
LOOP LDAA 0,Y ;prepare parameter to pass (by-value in A)
JSR SQUARE ;square it, i.e., B = MSB of (A).(A)
ABX ;sum=sum+B (SQUARE put result in B)
INY ;increment data block pointer
CPY #$4100 ;squared all data?
BNE LOOP ;get more if not done yet
SWI
; ------------------------ End of MAIN ---------------------
; SUBROUTINE SQUARE calculates the square of an 8-bit number
; as a rounded 8-bit normalized result
; calling registers: A = data to be squared
; return registers: B = rounded 8-bit normalized square
SQUARE TAB
MUL
ADCA #$00 ;round it to 8-bit result
TAB ;move approx squared rounded # in B
RTS
* -----------------------END OF SUBROUTINE SQUARE ----------35 35
CALL-BY-VALUE ( -> Stack)
; Adds 10 bytes (from a buffer stored in memory) passed onto
; the stack and returns the sum in the A register Demo LEAS instructions
NUM: EQU 10 ; Number of bytes to add
PROG: EQU $0800 ; Program location ; Subroutine to calculate a sum of NUM bytes on the stack.
DATA: EQU $0900 ; Input: B register contains the number to add
STACK: EQU $0a00 ; Top of the stack ; Output: A register contains the sum
ORG PROG ; Registers Modified: A, B and CCR
lds #STACK CalcSum:
; Push NUM bytes on the stack from an arbitrary buffer ; When the subroutine is entered, the SP is pointing
ldab #NUM ; Initialize counter in B ; to the return address. Use it to get address of data into X.
ldx #BUF ; Initialize X pointer leax 2,SP ; SP+2 -> X
; DO get the data ; Now get the data and add it all up
LoadLoop: ldaa 0,x ldaa 1,X+ ; Get first byte
; and put it on the stack decb ; Adjust the counter
psha add_loop:
inx ; Increment the pointer ; DO add the byte the SP is pointing to, and then
; WHILE the counter is not equal to zero ; increment the SP to point to the next byte
dbne b,LoadLoop adda 1,X+
; Calculate the sum ; WHILE the counter is not equal to zero
ldab #NUM dbne b,add_loop
jsr CalcSum ; A register has the sum, restore the SP to pointing
; After returning from the subroutine, you can check ; to the return address.
; the carry bit for an overflow and you can rts ; Return to the program
; restore the stack pointer ; Set up the data buffer area and put some data in it
leas NUM,SP ORG DATA
36 36
swi BUF: DC.B 1,2,3,4,5,6,7,8,9,10
Appel par référence (call-by-reference)

Pointeur de mémoire
◼ Passer le sous-programme d'une valeur de
registre contenant l'adresse des paramètres
en mémoire.
◼ Plus complexe, une charge supplémentaire
pour l'utilisation du pointeur.

37
CALL-BY-REFERENCE (-> register)
;X sum of B*B
RES EQU $407E ; GLOBAL VARIABLE RES
;MAIN ORG $4000 ;start address
LDX #0 ;init sum S = 0
LDY #$4080 ;init. data block pointer & prepare parameter to pass
;(by-reference - register Y, i.e., ptr to operand is in Y)
LOOP JSR SQUARE ;square it B = b*b
LDAB RES
ABX ;sum=sum+B
INY ;increment data block pointer
CPY #$4100 ;squared all data?
BNE LOOP ;get more if not
SWI
* SUBROUTINE SQUARE calculates the square of an 8-bit number as a rounded 8-bit #
* calling registers: Y = pointer to data to be squared
* return registers: B = rounded 8-bit normalized square
SQUARE LDAB 0,Y ; B <- m(Y)
TBA ;
MUL
ADCA #$00 ;round it to 8-bit result
STAA RES ;put result at RES (by-value - GLOBAL VARIABLE RES)
RTS
* End of program code Y 4080
* DATA MAIN SQUARE
ORG $4080
RES: M(407F) X2 38 38
Données constantes
◼ Emplacement
 Utilisez la directive ORG
 Normalement placé à la fin du code (destiné
pour le ROM)
 Définir la section de données constantes avec
la directive SECTION (voir Module 3)
◼ Allocation
 Utilisez la directive assembleur DC

39
Données Variables
◼ Emplacement
 Utilisez la directive ORG pour placer les variables en RAM
 Définir la section de données variables avec la directive
SECTION (voir Module 3)
◼ Allocation
 Utilisez les directives d’assembleurs DC et DS
 Initialiser avec le code les variables

40
Autres principes de codage
◼ Indentation ou non
 Typiquement, le code assembleur n’utilise pas l’indentation
◼ Lettres majuscules et minuscules
 Certains assembleurs ne sont pas sensibles à la case
 Rendre les étiquettes plus faciles à lire
 Tout en majuscule pour les constantes
◼ Utilisez des symboles et non des chiffres magiques
 Permet d’avoir un code qui se documente
◼ Les fichiers “include”
 Avec la directive “include”, il est possible d’insérer d’autres fichiers
 Par exemple, définir des constantes communes et l’inclure dans un
nombre de fichiers assembleur
 Définition de modules réutilisables
◼ Utilisez les sous-programmes des moniteurs
◼ Style de commentaires
 Commentaire sur chaque ligne
 Commentaire pour un bloc de code
 Inclure dans les commentaires, le pseudo-code
41
Programmation structurée
◼ IF-ELSE
 testwin
◼ IF-ELSEIF
 checkLine
◼ DO-WHILE and WHILE-DO
 clrbrd, showbrd, prtbrdln
◼ Using Breaks
 testWin, isdraw
◼ Voir Cady Section 8.2 pour d’autres exemples

42
Expressions complexes de test
◼ do { … } while( (var1<10) && (var2>3));

do:
… ;{…}
ldaa var1 ; while( (var1 < 10)
cmpa #10
bhs endwhile
ldaa var2 ; && (var2 > 3)
cmpa #3
bhi do
endwhile: ; );
43
Expressions complexes de test
◼ if( (var1=3) || (var1=2) ) {…} else {…}

ldaa var1 ; if((var=3)


cmp #3
beq then
ldaa var1 ; || (var1=2)
cmp #2
bne else ; )
then:

bra endif
else:

endif:
44
Débogage –
avec
analyse
◼ Une approche
d’analyse facilite
la correction
d’erreurs de
programmation
 Trouvez ce que
fait le programme
avant de faire des
corrections
 Tentez de
comparer ce que
vous pensez ce
que le
programme fait à
ce qu’il fait
réellement
45
Revue de projet (walkthrough)
◼ Aussi appelé revue de code par paires (peer
code reviews)
◼ Technique de débogage efficace
◼ Élimine des erreurs avant de rouler le code
◼ Invite d’autres experts familiers et non-familiers
avec le projet
 Obtenirdu feedback au sujet d’erreurs, mais aussi
pour améliorer la conception et le code
◼ Utilisez la revue de projet dans la préparation de
labos avec votre partenaire.
46
Plan de débogage
◼ Utilisez une conception structurée
 Le code sera divisé en blocs bien définis
(avec sous-programmes et modules)
 L’utilisation du C pour la conception aide a
produire une conception structurée
◼ Permet la possibilité d’isoler le problème à
un bloc de code
 Peux établir des points d’arrêt après chaque
bloc pour voir quel(s) bloc(s) cause l’erreur
47
Outils de débogage
◼ Débogueurs
 Logiciel qui contrôle l’exécution d’un ;programme
 Peut être assez sophistiqué (sur carte d’évaluation,
les
programmes moniteurs offre des fonctions de débogages)
◼ Tracer un programme
 Exécuter une instruction à la fois
◼ Points d’arrêts
 Définit
les conditions pour arrêter l’exécution d’un
programme
 Typiquement établit à une instruction de programme
◼ Certains débogueurs permettent des conditions basées sur les
valeurs de données
◼ D’autres offrent des points d’arrêt de matériel (patron sur bus)

48
Déboguage d’éléments de données
◼ Que doit on examiner durant l’exécution du
programme:
 Registres: Contenu des registres, y comprit de CCR
 Mémoire:
◼ Les débogueurs haut niveau permettent d’examiner les
variables déclarées
◼ Avec les débogueurs de bas niveau, doit examiner la
mémoire en format hexadécimal
◼ Doit suivre le code source
 Le code source est nécessaire pour suivre la logique
du programme
 Le fichier « *.LST » qui montre le code machine est
très utile
◼ Peut souvent montré des erreurs en l’examinant
◼ Permet de savoir ou établir les points d’arrêt
49
Bugs typiques
◼ Mauvais transfert aux sous-programmes
◼ Oublier d’initialiser le pointeur de pile
◼ Pas assez de mémoire dans la pile
◼ Opérations de pile non balancées
◼ Sous-programmes qui détruisent des registres
◼ Registres transposés
◼ Oublier d’initialiser les registres index
◼ Oublier d’initialiser des registres ou données
◼ Modifier les codes d’états avant les instructions de
branchements
◼ Utilisez la mauvaise instruction de branchement
◼ Utilisez le mauvais mode d’adressage
◼ L’utilisation d’un compteur de 16-bit en mémoire
◼ Ne pas arrêter le programme correctement 50
Quelques trucs
◼ Utiliser l’adressage de registre lorsque possible
 Plus rapide et utilise moins de mémoire
◼ Utiliser l’adressage indexé ou indirect de registre
 Le prochain mode d’adressage le plus efficace
 Calcule les adresse durant l’exécution
◼ La pile pour stockage temporaire
 Dans les sous-programmes, attentions aux opérations balancées
◼ N’utiliser pas des numéros codés dans les instructions (magic #)
 Utilisez des étiquettes qui représentent des constantes
◼ Ne faîtes pas d’initialisation des données avec l’assembleur
 L’initialisation se fait seulement lors du téléchargement (ou dans un
ROM)
◼ Utilisé les fonctions de l’assembleurs
 Utiliser des étiquettes, des expressions, et des macros
◼ Utiliser mais n’abuser pas des commentaires
 MOV B,C ; Transfert de C à B ---- Pas significatif
 MOV B,C ; Réinitialiser le compteur

51

Vous aimerez peut-être aussi