Ordinateurs, Structure et Applications GIF-1001 Cours 9, Branchements et Pile Etienne Tremblay Université Laval, Hiver 2012 GIF-1001 Cours 9, p.1 Énoncés conditionnels et sauts, principe • • • • • • • L’instruction JMP Address permet de mettre IP à la valeur désignée par Address. JMP permet un saut à l’intérieur du code segment. Comme les adresses des instructions sont difficiles à retenir et qu’elles peuvent changer lorsque le programme change, des labels ont été inventés. Un label est une étiquette remplaçant l’adresse d’une instruction. L’instruction JMP exécute un saut inconditionnel. Les instructions JZ, JC, JS exécutent des sauts conditionnels. Elles changeront la valeur de IP si les drapeaux ont la valeur appropriée. Si les drapeaux n’ont pas la bonne valeur, l’instruction est ignorée et la prochaine instruction est exécutée. Par exemple, JZ MonLabel sautera à l’instruction indiquée par MonLabel si le drapeau Zéro est à 1. L’instruction CMP A,B a le même effet qu’une soustraction sur les drapeaux, mais elle ne change pas la valeur de A. Cette instruction est utile pour créer des énoncés conditionnels du genre if(A != B). if(A != B) se traduirait par CMP A,B, suivi de JNZ CodeAExecuterSiVrai. La plupart des instructions de saut n’utilisent qu’un drapeau. Cependant, certaines comparaisons (<,>) requièrent des tests sur deux drapeaux (Zéro et (Overflow OU Carry)). Les drapeaux utilisés pour évaluer une condition peuvent être différents si les nombres comparés sont signés ou non-signés. Voir JG, JLE, JA… GIF-1001 Cours 9, p.2 Instructions de saut (1 drapeau seulement) JZ Saut si zéro. JNZ JE Saut si égal. JC Saut si Retenue (inférieur). JNC JB Saut si inférieur. JNB JNAE Saut si ni supérieur ni égal. CF = 1 JAE JS Saut si signe négatif. SF = 1 JNS JO Saut si débordement. OF = 1 JNO JPE Saut si parité paire. JP Saut si parité. PF = 1 JPO JNZ Saut si pas zéro. JNE Saut si différent. JNC Saut si pas de retenue. JC JNB Saut si pas inférieur. JB JAE Saut si supérieur ou égal. CF = 0 JNAE JNS Saut si aucun signe (positif). SF = 0 JS JNO Saut si pas de débordement. OF = 0 JO JPO Saut si parité impaire. JNP Saut si pas de parité. ZF = 1 JNE JZ ZF = 0 JE JPE PF = 0 JP GIF-1001 Cours 9, p.3 Exemple de boucle • Le code qui suit est un exemple de calcul de factoriel (Le nombre doit être entre 0 et 8! = 40320 afin d’éviter un Overflow. Le nombre est dans CX au début et la résultat est dans AX à la fin. Les registres BX et DX sont modifiés par le programme. GIF-1001 Cours 9, p.4 Sauts relatifs, absolus et indirects • • • L’instruction JMP Address est compilée comme étant une instruction qui change IP par rapport à sa valeur actuelle: JMP Address est une instruction qui effectue IP = IP + X, X étant la différence entre l’adresse de l’instruction JMP Address et l’adresse de la destination du saut. On parle de saut relatif (à la valeur de IP) parce que le paramètre Address ne désigne pas une adresse de la mémoire, mais plutôt un déplacement par rapport à l’adresse actuelle. Un saut absolu est un saut dans lequel l’adresse de la destination est indiquée entièrement dans l’instruction de saut (IP = adresse). Les sauts absolus sont rares par rapport aux sauts relatifs: ils prennent plus d’espace mémoire (il faut plus de bits pour décrire une adresse absolue qu’un déplacement) et ils diminuent la modularité du code. L’instruction JMP Address est une instruction de saut direct: la destination du saut est fixe et définie à même l’instruction. Le 8086 permet des sauts indirects, c’est-à-dire des sauts dont l’adresse de destination est définie par un registre (exemple: JMP AX). Les sauts indirects permettent d’implémenter plusieurs éléments des langages de haut niveau comme les “switch case” ou les pointeurs de fonction. GIF-1001 Cours 9, p.5 La pile et les sous-routines • Voir le document de monsieur Philippe Leray, INSA (ASI) de Rouen: Pile_SousRoutines_Ints.pdf • • Tous les langages de programmation permettent de construire des sous-routines, c’est-à-dire des fonctions qui peuvent être appelées de plusieurs endroits dans le code. Les sous-routines permettent d’éviter la duplication de code lorsque des opérations identiques sont effectuées à des endroits différents dans un programme. En assembleur 8086, une sous-routine est appelée avec l’instruction CALL (exemple CALL MaFonction). L’instruction CALL a deux effets: – Sauvegarder l’adresse de retour sur la pile – Changer IP (IP = adresse de MaFonction) • En assembleur 8086, une sous-routine est habituellement terminée par l’instruction RET. L’instruction RET a deux effets: – Récupérer l’adresse de retour sur la pile – Changer IP (IP = adresse de retour) • L’adresse de retour est l’adresse de l’instruction qui suit l’instruction CALL. GIF-1001 Cours 9, p.6 La pile et les sous-routines • • • • • • Voir le document de monsieur Philippe Leray, INSA (ASI) de Rouen: Pile_SousRoutines_Ints.pdf La pile est une structure de donnée qui permet d’empiler et de dépiler des données. Le pile est un espace de la mémoire qui est géré comme une pile de feuilles: mettre ou retirer une donnée se fait toujours à partir du dessus de la pile. L’instruction PUSH permet de mettre une donnée sur la pile. L’instruction PUSH met 2 octets sur la pile. L’instruction POP permet de récupérer une donnée de la pile. L’instruction POP retire 2 octets de la pile. La pile du 8086 est une pile descendante: les données sont empilées du haut de la mémoire vers le bas de la mémoire. La pile est construite ainsi parce que les instructions et les données d’un programme sont habituellement dans le bas de la mémoire et la pile, dans le haut de la mémoire. Le registre SP (Stack Pointer) désigne l’adresse du dessus de la pile. Il est modifié automatiquement par le microprocesseur lors de PUSH, POP, CALL, RET et autres instructions qui utilisent la pile. GIF-1001 Cours 9, p.7 La pile et les sous-routines • • • Voir les supports de monsieur Philippe Leray, INSA (ASI) de Rouen: Pile_SousRoutines_Ints.pdf Des mots réservés permettent de déclarer une procédure: ces mots permettent de rattacher une étiquette ou un nom de fonction à l’adresse d’une sous-routine. Plusieurs sous-routines ou fonctions reçoivent des paramètres d’entrées et produisent un résultat: par exemple la sous-routine Moyenne reçoit des nombres en entrée et retourne la moyenne en sortie. En assembleur, il y a plusieurs façons de passer des paramètres: par registre, par la pile et par variables globales. – Passage de paramètres par registre: les valeurs traitées par la fonction et le résultat du calcul sont dans des registres prédéterminés. – Passage de paramètres par la pile: les valeurs traitées par la fonction et le résultat du calcul sont placés sur la pile à des endroits relatifs au pointeur de pile, prédéterminés. – Passage de paramètres par variable globale: les valeurs traitées par la fonction et le résultat du calcul sont placés dans la mémoire à des endroits prédéterminés. • Les paramètres d’une fonction peuvent être des valeurs ou bien des adresses. Lorsque les paramètres sont des adresses, on parle de passage de paramètres par référence. GIF-1001 Cours 9, p.8 Macros • • • • • Une macro est une série d’instructions prédéfinies, à l’instar d’une sousroutine. Lors du pré assemblage, le code contenu dans la macro est copié à tous les endroits où apparaissent la macro alors que le code d’une sous-routine n’est habituellement qu’à un seul endroit de la mémoire. Il est possible de voir une macro comme une constante, mais pour du code: lors du pré assemblage, les constantes sont remplacées par leur valeurs et les macros sont remplacées par des instructions. Les macros servent à éviter de écrire plusieurs fois du code qui revient souvent dans le programme mais pour lequel on ne veut pas faire de procédure afin de gagner du temps de calcul (éviter l’appel de la procédure , le passage de paramètres,, etc.). Comme le code contenu dans une macro est copié pour toutes les instances de la macro, un programme avec des macros sera habituellement plus gros qu’un programme avec des procédures. L’instruction pour définir une macro est: – nom MACRO [paramètres,...] • <instructions> – ENDM GIF-1001 Cours 9, p.9 Exemple de macro • Le programme qui suit met d’abord 1, 2 et 3 dans AX,BX et CX respectivement. Ensuite, il met 4, 5 et DX dans AX,BX et CX respectivement. • • MyMacro MACRO p1, p2, p3 – MOV AX, p1 – MOV BX, p2 – MOV CX, p3 ENDM • • • • ORG 100h MyMacro 1, 2, 3 MyMacro 4, 5, DX RET GIF-1001 Cours 9, p.10 Instructions d’I/Os (IN, OUT) • • • Le 8086 peut accéder à 64K adresses pour les I/Os (Registres de 16bits!!!) Le processus pour accéder aux I/Os est le même à l’intérieur de l’ordinateur que pour accéder à la mémoire: les mêmes lignes d’adresse sont utilisées (du moins 16 sur 20), les mêmes lignes de données sont utilisées et les lignes de lecture/écriture servent dans les deux cas. Une ligne additionnelle M/IO* sert à déterminer si la mémoire ou des I/O sont adressés. Pour accéder à un périphérique, les instructions IN et OUT sont utilisées. IN et OUT ont deux opérandes (adresse de I/O –port- et destination/source. Adresse peut être une valeur immédiate de 8bits ou le registre DX (16bits). – Notez que l’opcode de IN ou de OUT n’a qu’un seul paramètre (le port choisi) ou aucun. AX ou AL est toujours utilisé comme source ou destination. Lorsqu’on veut spécifier un port avec un registre, DX est automatiquement choisi. En raison de son implémentation dans le 8086, seuls AX et DX peuvent être utilisés avec IN et OUT. • Exemples: – IN dst, adresse • IN AL, 10 • IN AX, DX ;Met dans AL les 8 bits donnés par l’I/O à l’adresse 10d. ;Met dans AX les 16 bits donnés par l’I/O à l’adresse pointée par DX – OUT adresse, src • OUT 4, AX • OUT DX, AL ;Met les 16 bits de AX dans l’I/O à l’adresse 4. ;Met les 8 bits de AL dans l’I/O à l’adresse pointée par DX. GIF-1001 Cours 9, p.11 Références et exercices • Références – Irv Englander: chapitre 7 (7.8 plus particulièrement), chapitre 12 (jusqu’à la page 351). – http://www.commentcamarche.net/asm/assembleur.php3 – http://www.ifrance.com/zarbi-os/DOCS/chap2.htm (très bon résumé) – Didacticiel de EMU8086 – datasheet du 8086 sur le site web du cours – Pile_SousRoutines_Ints.pdf de monsieur Philippe Leray • Exercices – Lire le didacticiel de EMU8086 GIF-1001 Cours 9, p.12 Annexe A: Autres Microprocesseurs • • • • • Le 8086 supporte des instructions qui accède à la mémoire tout en faisant des opérations mathématiques. Dans la plupart des microprocesseurs modernes, seules les instructions LOAD et STORE permettent de lire ou écrire la mémoire. Cela simplifie grandement le design du microprocesseur et permet un pipeline d’instructions fonctionnel. La plupart des microprocesseurs modernes supportent des instructions arithmétiques avec trois opérandes. Par exemple, ADD R1, R2, R3 permettra d’effectuer R1 = R2 + R3. Les instructions de saut conditionnel du 8086 utilisent les drapeaux de l’ALU. Dans la plupart des microprocesseurs, l’approche utilisée est de tester un registre. À la place de CMP AX, 0 suivi de JZ qqpart, on retrouvera, par exemple, BZ AX, qqpart. BZ AX, qqpart signifie: effectue un Branchement vers qqpart si AX est Zéro. Lorsque le 8086 appelle une fonction avec l’instruction CALL, l’adresse de retour est mise automatiquement sur la pile par le microprocesseur. Pour éviter cet accès mémoire, plusieurs microprocesseurs mettent l’adresse de retour dans un registre, le registre de lien, plutôt que sur la pile. C’est au programmeur de sauvegarder le registre de lien sur la pile si sa fonction appelle d’autres fonctions. Les instructions In et Out activent la broche M/IO*. Cette broche sert à distinguer les adresses de mémoire des adresses de périphériques de telle sorte que l’adresse 0 peut désigner le premier mot de la mémoire ou le premier port de périphérique. Dans plusieurs systèmes ayant plus d’adresses (32 bits!), la mémoire et les périphériques partagent le même espace d’adresses: la même instruction (LOAD ou MOV) permet de lire indifféremment à la mémoire ou un périphérique, en fonction de l’adresse choisie. GIF-1001 Cours 9, p.13