Programme de langage d'assemblage. Caractéristiques générales du système de commandes du langage Assembleur pour IBM-PC (jeu de commandes de base, modes d'adressage de base des opérandes). La structure du programme en langage Assembleur. Commandes en langage d'assemblage

informations généralesà propos du langage d'assemblage

Le langage d'assemblage symbolique permet d'éliminer en grande partie les lacunes de la programmation en langage machine.

Son principal avantage est qu'en langage assembleur tous les éléments du programme sont représentés sous forme symbolique. La transformation des noms de commandes symboliques en leurs codes binaires est de la responsabilité de programme spécial- assembleur, qui libère le programmeur d'un travail laborieux et élimine les erreurs inévitables.

Les noms symboliques introduits lors de la programmation en langage d'assemblage reflètent généralement la sémantique du programme et l'abréviation des commandes - leur fonction principale. Par exemple : PARAM - paramètre, TABLE - table, MASK - masque, ADD - addition, SUB - soustraction, etc. n. De tels noms sont facilement mémorisés par le programmeur.

Pour programmer en langage assembleur, il faut disposer d'outils plus complexes que pour programmer en langage machine : il faut des systèmes informatiques à base de micro-ordinateurs ou de PC avec un ensemble périphériques(clavier alphanumérique, afficheur de caractères, disquette et imprimante), ainsi que des systèmes de programmation résidente ou croisée pour les types de microprocesseurs requis. Le langage d'assemblage vous permet d'écrire et de déboguer efficacement des programmes beaucoup plus complexes que le langage machine (jusqu'à 1 à 4 Ko).

Les langages d'assemblage sont orientés machine, c'est-à-dire dépendants du langage machine et de la structure du microprocesseur correspondant, puisqu'ils attribuent un nom symbolique spécifique à chaque instruction du microprocesseur.

Les langages d'assemblage offrent une augmentation significative de la productivité des programmeurs par rapport aux langages machine et conservent en même temps la possibilité d'utiliser toutes les ressources matérielles accessibles par logiciel du microprocesseur. Cela permet aux programmeurs expérimentés d'écrire des programmes qui s'exécutent dans plus de un bref délais et occupant moins de mémoire que les programmes écrits dans un langage de haut niveau.

À cet égard, presque tous les programmes de contrôle de périphériques d'E / S (pilotes) sont écrits en langage d'assemblage, malgré la présence d'une gamme assez large de langages de haut niveau.

En utilisant le langage assembleur, le programmeur peut définir les paramètres suivants :

mnémonique (nom symbolique) de chaque commande du langage machine du microprocesseur ;

format standard des lignes d'un programme décrit en assembleur ;

format de spécification différentes manières options d'adressage et de commande ;

format pour spécifier des constantes de caractères et des constantes de type entier dans divers systèmes de numération ;

pseudo-commandes qui contrôlent le processus d'assemblage (traduction) du programme.

En langage assembleur, le programme est écrit ligne par ligne, c'est-à-dire qu'une ligne est allouée à chaque instruction.

Pour les micro-ordinateurs construits sur la base des types de microprocesseurs les plus courants, il peut exister plusieurs variantes de langage d'assemblage, cependant, on a généralement une distribution pratique - c'est ce qu'on appelle le langage d'assemblage standard

La programmation au niveau des instructions machine est le niveau minimum auquel la programmation est possible. Le système d'instructions machine doit être suffisant pour mettre en œuvre les actions requises en envoyant des instructions au matériel informatique.

Chaque instruction machine se compose de deux parties :

fonctionnement - déterminer "que faire" ;

· opérande - définissant les objets de traitement, "que faire avec".

L'instruction machine du microprocesseur, écrite en langage assembleur, est une seule ligne avec la forme syntaxique suivante :

label commande/directive opérande(s) ; commentaires

Dans ce cas, un champ obligatoire dans une ligne est une commande ou une directive.

L'étiquette, la commande/directive et les opérandes (le cas échéant) sont séparés par au moins un espace ou un caractère de tabulation.

Si une commande ou une directive doit être poursuivie sur la ligne suivante, le caractère barre oblique inverse est utilisé : \.

Par défaut, le langage d'assemblage ne fait pas la distinction entre les lettres majuscules et minuscules dans les commandes ou les directives.

Adressage direct: L'adresse effective est déterminée directement par le champ de décalage d'instruction machine, qui peut avoir une taille de 8, 16 ou 32 bits.

mov eax, somme ; eax = somme

L'assembleur remplace sum par l'adresse correspondante stockée dans le segment de données (par défaut, adressée par le registre ds) et place la valeur stockée à l'adresse sum dans le registre eax.

adressage indirectà son tour a les types suivants:

Adressage de base indirect (registre);

Adressage de base indirect (registre) avec décalage ;

· adressage d'index indirect ;

· adressage indirect d'index de base.

Adressage de base indirect (registre). Avec cet adressage, l'adresse effective de l'opérande peut être dans n'importe lequel des registres à usage général, à l'exception de sp / esp et bp / ebp (ce sont des registres spécifiques pour travailler avec un segment de pile). Syntaxiquement dans une instruction, ce mode d'adressage s'exprime en mettant le nom du registre entre crochets.

déplacer eax, ; eax = *esi; *valeur esi à l'adresse esi

Introduction.

Le langage dans lequel le programme original est écrit est appelé saisir langue, et la langue dans laquelle il est traduit pour exécution par le processeur - fin de semaine langue. Le processus de conversion d'une langue d'entrée en une langue de sortie est appelé diffuser.Étant donné que les processeurs sont capables d'exécuter des programmes en langage machine binaire, qui n'est pas utilisé pour la programmation, la traduction de tous les programmes sources est nécessaire. connu deux façons traductions : compilation et interprétation.

À compilation le programme source est d'abord complètement traduit en un programme équivalent dans la langue cible, appelé objet programme puis exécuté. Ce processus est effectué à l'aide d'un programmes, appelé compilateur. Un compilateur pour lequel le langage d'entrée est une représentation symbolique du langage machine (de sortie) des codes binaires est appelé assembleur.

À interprétations chaque ligne de texte du programme source est analysée (interprétée) et la commande qui y est spécifiée est immédiatement exécutée. La mise en œuvre de cette méthode repose sur programme d'interprétation. L'interprétation prend beaucoup de temps. Pour augmenter son efficacité, au lieu de traiter chaque ligne, l'interpréteur convertit au préalable toutes commande chaînes en caractères (

). La séquence de symboles générée est utilisée pour exécuter les fonctions attribuées au programme d'origine.

Le langage d'assemblage décrit ci-dessous est implémenté à l'aide de la compilation.

Caractéristiques de la langue.

Les principales caractéristiques de l'assembleur :

● au lieu de codes binaires, le langage utilise des noms symboliques - mnémotechnique. Par exemple, pour la commande d'addition (

) mnémonique est utilisé

Soustractions (

multiplier (

Divisions (

etc. Des noms symboliques sont également utilisés pour adresser des cellules de mémoire. Pour programmer en langage assembleur, au lieu de codes binaires et d'adresses, vous n'avez besoin de connaître que les noms symboliques que l'assembleur traduit en codes binaires ;

chaque énoncé correspond une commande machine(code), c'est-à-dire qu'il existe une correspondance biunivoque entre les instructions machine et les opérateurs dans un programme en langage assembleur ;

● la langue donne accès à tous les objets et équipes. Les langages de haut niveau n'ont pas cette capacité. Par exemple, le langage d'assemblage vous permet de vérifier un bit de registre d'indicateur et un langage de haut niveau (par exemple,

) n'a pas cette capacité. Notez que les langages de programmation système (par exemple, C) occupent souvent une position intermédiaire. En termes d'accessibilité, ils sont plus proches du langage d'assemblage, mais ils ont la syntaxe d'un langage de haut niveau ;

● langage d'assemblage n'est pas une langue universelle. Chaque groupe spécifique de microprocesseurs possède son propre assembleur. Les langages de haut niveau n'ont pas cet inconvénient.

Contrairement aux langages de haut niveau, écrire et déboguer un programme en langage assembleur prend beaucoup de temps. Malgré cela, le langage d'assemblage est devenu large utilisation en raison des circonstances suivantes :

● Un programme écrit en langage assembleur est beaucoup plus petit et beaucoup plus rapide qu'un programme écrit dans un langage de haut niveau. Pour certaines applications, ces indicateurs jouent un rôle primordial, par exemple, de nombreux programmes système (y compris des compilateurs), des programmes de cartes de crédit, téléphones portables, pilotes de périphériques, etc. ;

● certaines procédures nécessitent accès total au matériel, ce qui n'est généralement pas possible dans un langage de haut niveau. Ce cas inclut les interruptions et les gestionnaires d'interruptions dans les systèmes d'exploitation, ainsi que les contrôleurs de périphériques dans les systèmes embarqués en temps réel.

Dans la plupart des programmes, seul un petit pourcentage du code total est responsable d'un grand pourcentage du temps d'exécution du programme. En règle générale, 1 % du programme est responsable de 50 % du temps d'exécution et 10 % du programme est responsable de 90 % du temps d'exécution. Par conséquent, pour écrire un programme spécifique dans des conditions réelles, l'assembleur et l'un des langages de haut niveau sont utilisés.

Format d'opérateur en langage assembleur.

Un programme en langage assembleur est une liste de commandes (instructions, phrases), dont chacune occupe une ligne distincte et contient quatre champs : un champ d'étiquette, un champ d'opération, un champ d'opérande et un champ de commentaire. Chaque champ a une colonne distincte.

Champ d'étiquette.

La colonne 1 est allouée au champ de libellé. Un libellé est un nom symbolique, ou identifiant, adresses mémoire. Il est nécessaire pour pouvoir :

● faire une transition conditionnelle ou inconditionnelle vers la commande ;

● accéder à l'endroit où les données sont stockées.

Ces déclarations sont étiquetées. Pour désigner un nom, on utilise des lettres (majuscules) de l'alphabet anglais et des chiffres. Le nom doit commencer par une lettre et se terminer par deux-points. L'étiquette deux-points peut être écrite sur une ligne séparée, et l'opcode peut être écrit sur la ligne suivante dans la colonne 2, ce qui simplifie le travail du compilateur. L'absence de deux-points rend impossible la distinction entre une étiquette et un opcode s'ils sont sur des lignes séparées.

Dans certaines versions du langage d'assemblage, les deux-points sont placés uniquement après les étiquettes d'instructions, pas après les étiquettes de données, et la longueur des étiquettes peut être limitée à 6 ou 8 caractères.

Le champ label ne doit pas contenir les mêmes noms, puisque le label est associé aux adresses des commandes. Si pendant l'exécution du programme, il n'est pas nécessaire d'appeler une commande ou des données de la mémoire, le champ d'étiquette reste vide.

Champ de code de transaction.

Ce champ contient le mnémonique ou la pseudo-commande de la commande (voir ci-dessous). Le code mnémonique de la commande est choisi par les développeurs du langage. En langage assembleur

mnémonique sélectionné pour charger le registre depuis la mémoire

), et de stocker le contenu du registre en mémoire - le mnémonique

). Dans les langages d'assemblage

vous pouvez utiliser le même nom pour les deux opérations, respectivement

Si le choix des noms mnémoniques peut être arbitraire, alors la nécessité d'utiliser deux instructions machine est due à l'architecture du processeur

Les mnémoniques des registres dépendent également de la version de l'assembleur (tableau 5.2.1).

Champ opérande.

Ici se trouve Informations Complémentaires nécessaire pour effectuer l'opération. Dans le champ des opérandes pour les instructions de saut, l'adresse où vous voulez sauter est indiquée, ainsi que les adresses et les registres qui sont des opérandes pour l'instruction machine. A titre d'exemple, voici les opérandes utilisables pour les processeurs 8 bits

● données numériques,

présentés dans différents systèmes de numération. Pour indiquer le système numérique utilisé, une constante est suivie de l'un des Lettres latines: DANS,

En conséquence, les systèmes de numération binaire, octal, hexadécimal, décimal (

peut ne pas être enregistré). Si le premier chiffre du nombre hexadécimal est A, B, C,

Ensuite, un 0 (zéro) non significatif est ajouté devant ;

● codes des registres internes du microprocesseur et des cellules mémoire

M (sources ou récepteurs d'informations) sous la forme des lettres A, B, C,

M ou leurs adresses dans n'importe quel système de numérotation (par exemple, 10V - adresse de registre

en système binaire);

● identifiants,

pour les paires d'avions immatriculés,

Les premières lettres B

H; pour une paire d'accumulateur et de registre de fonctions -

; pour le compteur de programme -

; pour le pointeur de pile -

● étiquettes indiquant les adresses des opérandes ou instructions suivantes au conditionnel

(lorsque la condition est remplie) et transitions inconditionnelles. Par exemple, l'opérande M1 dans la commande

signifie la nécessité d'une transition inconditionnelle vers la commande, dont l'adresse dans le champ d'étiquette est marquée avec l'identifiant M1 ;

● expression,

qui sont construits en reliant les données décrites ci-dessus à l'aide d'opérateurs arithmétiques et logiques. Notez que la manière dont l'espace de données est réservé dépend de la version du langage. Développeurs de langage d'assemblage pour

Définir le mot), et introduit plus tard Option alternative.

qui dès le début était dans le langage des processeurs

En version linguistique

utilisé

définir une constante).

Les processeurs traitent des opérandes de longueurs différentes. Pour le définir, les développeurs assembleurs ont pris différentes décisions, par exemple :

Les registres II de différentes longueurs ont des noms différents : EAX - pour placer des opérandes 32 bits (type

); AX - pour 16 bits (type

et AN - pour 8 bits (type

● pour les processeurs

des suffixes sont ajoutés à chaque opcode : suffix

Pour le genre

; suffixe ".B" pour le type

pour des opérandes de longueurs différentes, différents opcodes sont utilisés, par exemple pour charger un octet, un demi-mot (

) et les mots dans le registre 64 bits utilisent des opcodes

respectivement.

Champ de commentaires.

Ce champ fournit des explications sur les actions du programme. Les commentaires n'affectent pas le fonctionnement du programme et sont destinés à une personne. Ils peuvent être nécessaires pour modifier un programme qui, sans ces commentaires, peut être complètement incompréhensible même pour les programmeurs expérimentés. Un commentaire commence par un caractère et est utilisé pour expliquer et documenter les programmes. Le caractère de début d'un commentaire peut être :

● point-virgule (;) dans les langues pour les sous-traitants de l'entreprise

Point d'exclamation(!) dans les langues pour

Chaque ligne distincte réservée à un commentaire est précédée d'un caractère de début.

Pseudo commandes (directives).

En langage assembleur, on distingue deux grands types de commandes :

basique instructions équivalentes au code machine du processeur. Ces commandes effectuent tout le traitement fourni par le programme ;

pseudo-commandes ou directives, conçu pour servir le processus de traduction du programme dans le langage des combinaisons de codes. A titre d'exemple, dans le tableau. 5.2.2 montre quelques pseudo-commandes de l'as-assembleur

pour la famille

.

Lors de la programmation, il existe des situations où, selon l'algorithme, la même chaîne de commandes doit être répétée plusieurs fois. Pour sortir de cette situation, vous pouvez :

● écrire la séquence de commandes souhaitée chaque fois qu'elle se produit. Cette approche conduit à une augmentation du volume du programme ;

● organiser cette séquence dans une procédure (sous-programme) et l'appeler si nécessaire. Une telle sortie a ses inconvénients : il faut à chaque fois exécuter une instruction d'appel de procédure spéciale et une instruction de retour, ce qui, avec une séquence courte et fréquemment utilisée, peut fortement réduire la vitesse du programme.

Le plus simple et méthode efficace la répétition répétée d'une chaîne de commandes consiste à utiliser macro, qui peut être considéré comme une pseudo-commande destinée à retraduire un groupe de commandes fréquemment rencontrées dans un programme.

Une macro, ou instruction de macro, est caractérisée par trois aspects : la définition de macro, l'inversion de macro et l'expansion de macro.

macro définition

Il s'agit d'une désignation pour une séquence répétée de commandes de programme, utilisée pour les références dans le texte du programme.

Une macro a la structure suivante :

Liste d'expressions ; macro définition

La structure de définition de macro ci-dessus comporte trois parties :

● en-tête

macro contenant le nom

Pseudo-commande

et un ensemble de paramètres ;

● pointillé corps macro;

● équipe

l'obtention du diplôme

macro définitions.

Un jeu de paramètres de macro contient une liste de tous les paramètres indiqués dans le champ d'opérande pour le groupe d'instructions sélectionné. Si ces paramètres sont donnés plus tôt dans le programme, ils peuvent être omis dans l'en-tête de définition de macro.

Pour le réassemblage du groupe d'instructions sélectionné, un appel est utilisé, composé du nom

macro et liste de paramètres avec d'autres valeurs.

Lorsque l'assembleur rencontre une définition de macro lors de la compilation, il la stocke dans la table de définition de macro. Avec des apparitions ultérieures dans le programme du nom (

) d'une macro, l'assembleur le remplace par le corps de la macro.

L'utilisation d'un nom de macro comme opcode s'appelle macro-inversion(appel de macro), et son remplacement par le corps de la macro - extension macro.

Si le programme est représenté comme une séquence de caractères (lettres, chiffres, espaces, ponctuation et retours chariot pour passer à une nouvelle ligne), alors l'expansion de la macro consiste à remplacer certaines chaînes de cette séquence par d'autres chaînes.

L'expansion de la macro se produit pendant le processus d'assemblage, pas pendant l'exécution du programme. Les manières de manipuler les chaînes de caractères sont attribuées à outils macros.

Le processus d'assemblage est effectué en deux passes :

● Lors de la première passe, toutes les définitions de macros sont conservées et les appels de macros sont développés. Dans ce cas, le programme source est lu et converti en un programme dans lequel toutes les définitions de macro sont supprimées et chaque appel de macro est remplacé par un corps de macro ;

● La deuxième passe traite le programme reçu sans macros.

Macros avec paramètres.

Pour travailler avec des séquences de commandes répétitives, dont les paramètres peuvent prendre différentes valeurs, des définitions de macro sont fournies :

● avec réel les paramètres qui sont placés dans le champ opérande de l'appel de macro ;

● avec officiel paramètres. Lors du développement de la macro, chaque paramètre formel qui apparaît dans le corps de la macro est remplacé par le paramètre réel correspondant.

en utilisant des macros avec des paramètres.

Le programme 1 montre deux séquences de commandes similaires, différant en ce que la première permute P et

Et le deuxième

Le programme 2 comprend une macro avec deux paramètres formels P1 et P2. Lors de l'expansion de la macro, chaque caractère P1 à l'intérieur du corps de la macro est remplacé par le premier paramètre réel (P,

), et le symbole P2 est remplacé par le deuxième paramètre réel (

) du programme n° 1. Dans un appel de macro

le programme 2 est marqué : P,

Le premier paramètre réel,

Le deuxième paramètre réel.

Programme 1

Programme 2

MOV EBX,Q MOV EAX,Pl

MOV Q,EAX MOV EBX,P2

MOV P,EBX MOV P2,EAX

Capacités étendues.

Considérez quelques fonctionnalités avancées du langage

Si une macro contenant une instruction de branchement conditionnel et une étiquette vers laquelle sauter est appelée deux fois ou plus, l'étiquette sera dupliquée (problème de duplication d'étiquette), ce qui provoquera une erreur. Par conséquent, chaque appel se voit attribuer (par le programmeur) une étiquette distincte en tant que paramètre. En langue

le label est déclaré local (

) et grâce aux fonctionnalités avancées, l'assembleur génère automatiquement une étiquette différente à chaque expansion de la macro.

vous permet de définir des macros à l'intérieur d'autres macros. Cette fonction avancée est très utile lorsqu'elle est associée à une liaison conditionnelle de programme. Considérer

SI WORDSIZE GT 16 M2 MACRO

La macro M2 peut être définie dans les deux parties de la déclaration

Cependant, la définition varie selon que le programme est assemblé sur un processeur 16 bits ou 32 bits. Si M1 n'est pas appelée, alors la macro M2 ne sera pas définie du tout.

Une autre fonctionnalité avancée est que les macros peuvent appeler d'autres macros, y compris elles-mêmes - récursif appel. Dans ce dernier cas, afin d'éviter une boucle infinie, la macro doit se passer un paramètre, qui change à chaque expansion, et aussi vérifier ce paramètre et termine la récursivité lorsque le paramètre atteint une certaine valeur.

Sur l'utilisation des macros en assembleur.

Lors de l'utilisation de macros, l'assembleur doit être capable d'effectuer deux fonctions : enregistrer les définitions de macro Et développer les appels de macro.

Enregistrement des définitions de macro.

Tous les noms de macro sont stockés dans une table. Chaque nom est accompagné d'un pointeur vers la macro correspondante afin de pouvoir l'appeler si nécessaire. Certains assembleurs ont une table séparée pour les noms de macros, d'autres ont une table commune dans laquelle, avec les noms de macros, il y a toutes les commandes et directives de la machine.

Lorsque vous rencontrez une macro lors de l'assemblage créé:

nouvel élément de tableau avec le nom de la macro, le nombre de paramètres et un pointeur vers une autre table de définition de macro où le corps de la macro sera stocké ;

● liste officiel paramètres.

Le corps de la macro, qui est simplement une chaîne de caractères, est ensuite lu et stocké dans la table de définition de macro. Les paramètres formels apparaissant dans le corps de la boucle sont marqués Caractère spécial.

Représentation interne d'une macro

de l'exemple ci-dessus pour le programme 2 (p. 244) est :

MOV EAX, MOV EBX, MOV MOV &

où le point-virgule est utilisé comme caractère de retour chariot et l'esperluette & est utilisé comme caractère de paramètre formel.

Extension d'appel macro.

Chaque fois qu'une définition de macro est rencontrée lors de l'assemblage, elle est stockée dans la table des macros. Lorsqu'une macro est appelée, l'assembleur suspend temporairement la lecture des données d'entrée à partir du périphérique d'entrée et commence à lire le corps de la macro enregistrée. Les paramètres formels extraits du corps de la macro sont remplacés par les paramètres réels et fournis par l'appel. Une esperluette & devant les paramètres permet à l'assembleur de les reconnaître.

Bien qu'il existe de nombreuses versions d'assembleur, les processus d'assemblage ont des caractéristiques communes et sont similaires à bien des égards. Le travail d'un assembleur à deux passes est considéré ci-dessous.

Assembleur en deux passes.

Le programme se compose d'un certain nombre d'opérateurs. Par conséquent, il semblerait que la séquence d'actions suivante puisse être utilisée lors de l'assemblage :

● le traduire en langage machine ;

● transférer le code machine reçu dans un fichier et la partie correspondante de la liste - dans un autre fichier ;

● répéter les procédures ci-dessus jusqu'à ce que l'intégralité du programme soit diffusée.

Cependant, cette approche n'est pas efficace. Un exemple est le soi-disant problème lien principal. Si la première instruction est un saut à l'instruction P à la toute fin du programme, l'assembleur ne peut pas la traduire. Il doit d'abord déterminer l'adresse de l'opérateur P, et pour cela il est nécessaire de lire tout le programme. Chaque lecture complète du programme original est appelée passage. Montrons comment nous pouvons résoudre le problème de référence directe en utilisant deux passes :

au premier passage collecter et stockez toutes les définitions de symboles (y compris les étiquettes) dans le tableau, et lors de la deuxième passe, lisez et assemblez chaque opérateur. Cette méthode est relativement simple, mais le deuxième passage dans le programme d'origine nécessite un temps d'E/S supplémentaire ;

● au premier passage, convertir programme dans un formulaire intermédiaire et enregistrez-le dans un tableau, et la deuxième passe est effectuée non pas selon le programme d'origine, mais selon le tableau. Cette méthode d'assemblage permet de gagner du temps, car aucune opération d'E/S n'est effectuée lors de la seconde passe.

Premier passage.

But du premier passage- construire une table de symboles. Comme indiqué ci-dessus, un autre objectif de la première passe est d'enregistrer toutes les définitions de macro et de développer les appels au fur et à mesure qu'ils apparaissent. Par conséquent, la définition des caractères et l'expansion des macros se produisent dans la même passe. Le symbole peut être soit étiqueter, ou signification, qui reçoit un nom spécifique à l'aide de la directive -you :

;Valeur - taille de la mémoire tampon

En donnant une signification aux noms symboliques dans le champ d'étiquette d'instruction, l'assembleur définit essentiellement les adresses que chaque instruction aura lors de l'exécution du programme. Pour ce faire, l'assembleur lors du processus d'assemblage enregistre compteur d'adresses d'instructions(

) comme variable spéciale. Au début de la première passe, la valeur de la variable spéciale est définie sur 0 et incrémentée après chaque commande traitée de la longueur de cette commande. A titre d'exemple, dans le tableau. 5.2.3 montre un fragment du programme indiquant la longueur des commandes et les valeurs des compteurs. Les tableaux sont générés lors de la première passe noms de symboles, directives Et codes de fonctionnement, et si nécessaire littéral tableau. Un littéral est une constante pour laquelle l'assembleur réserve automatiquement de la mémoire. On remarque tout de suite que les processeurs modernes contiennent des instructions avec des adresses directes, donc leurs assembleurs ne supportent pas les littéraux.

Tableau des symboles

contient un élément pour chaque nom (tableau 5.2.4). Chaque élément de la table des symboles contient le nom lui-même (ou un pointeur vers celui-ci), sa valeur numérique et parfois des informations supplémentaires, qui peuvent inclure :

● la longueur du champ de données associé au symbole ;

● bits de remappage mémoire (qui indiquent si la valeur d'un symbole change si le programme est chargé à une adresse différente de celle prévue par l'assembleur) ;

● des informations indiquant si le symbole est accessible depuis l'extérieur de la procédure.

Les noms symboliques sont des étiquettes. Ils peuvent être spécifiés à l'aide d'opérateurs (par exemple,

Tableau des directives.

Ce tableau répertorie toutes les directives, ou pseudo-commandes, qui surviennent lors de l'assemblage d'un programme.

Tableau des codes d'opération.

Pour chaque opcode, le tableau comporte des colonnes distinctes : désignation de l'opcode, opérande 1, opérande 2, valeur hexadécimale de l'opcode, longueur de l'instruction et type d'instruction (tableau 5.2.5). Les codes d'opération sont divisés en groupes selon le nombre et le type d'opérandes. Le type de commande détermine le numéro de groupe et spécifie la procédure qui est appelée pour traiter toutes les commandes de ce groupe.

Deuxième passe.

But de la deuxième passe- créer un programme objet et imprimer, si nécessaire, un protocole d'assemblage ; les informations de sortie nécessaires à l'éditeur de liens pour lier des procédures qui ont été assemblées à différents moments dans un fichier exécutable.

Dans la deuxième passe (comme dans la première), les lignes contenant les instructions sont lues et traitées les unes après les autres. L'opérateur d'origine et la sortie qui en est dérivée en hexadécimal objet le code peut être imprimé ou mis en mémoire tampon pour une impression ultérieure. Après avoir réinitialisé le compteur d'adresse de commande, la commande est appelée déclaration suivante.

Le programme d'origine peut contenir des erreurs, par exemple :

le symbole donné n'est pas défini ou défini plus d'une fois ;

● L'opcode est représenté par un nom invalide (en raison d'une faute de frappe), n'est pas fourni avec suffisamment d'opérandes ou contient trop d'opérandes ;

● pas d'opérateur

Certains assembleurs peuvent détecter un symbole indéfini et le remplacer. Cependant, dans la plupart des cas, lorsqu'une instruction contenant une erreur est trouvée, l'assembleur affiche un message d'erreur à l'écran et tente de poursuivre le processus d'assemblage.

Articles dédiés au langage assembleur.

Sujet 2.5 Notions de base sur la programmation du processeur

Au fur et à mesure que la durée du programme augmente, il devient plus difficile de se souvenir des codes pour diverses opérations. Les mnémoniques fournissent une aide à cet égard.

Le langage d'encodage des instructions symboliques est appelé assembleur.

langage d'assemblage est un langage dans lequel chaque instruction correspond exactement à une instruction machine.

Assemblée appelé convertir un programme à partir du langage assembleur, c'est-à-dire préparer un programme en langage machine en remplaçant les noms symboliques des opérations par des codes machine et les adresses symboliques par des nombres absolus ou relatifs, ainsi qu'inclure des programmes de bibliothèque et générer des séquences d'instructions symboliques en spécifiant des paramètres spécifiques dans les micro-instructions. Ce programme généralement placé dans la ROM ou entré dans la RAM à partir d'un support externe.

Le langage d'assemblage a plusieurs caractéristiques qui le distinguent des langages de haut niveau :

1. Il s'agit d'une correspondance un à un entre les instructions en langage assembleur et les instructions machine.

2. Le programmeur en langage assembleur a accès à tous les objets et commandes présents sur la machine cible.

Une compréhension des bases de la programmation dans les langages orientés machine est utile pour :



Meilleure compréhension de l'architecture des PC et meilleure utilisation des ordinateurs ;

Développer des structures plus rationnelles d'algorithmes pour les programmes de résolution de problèmes appliqués ;

La possibilité de visualiser et de corriger les programmes exécutables avec l'extension .exe et .com, compilés à partir de n'importe quel langage de haut niveau, en cas de perte des programmes sources (en appelant ces programmes dans le débogueur de programme DEBUG et en décompilant leur affichage en langage d'assemblage );

Compilation de programmes pour résoudre les tâches les plus critiques (un programme compilé dans un langage orienté machine est généralement plus efficace - plus court et plus rapide de 30 à 60% que les programmes obtenus à la suite d'une traduction à partir de langages de haut niveau)

Pour la mise en œuvre des procédures incluses dans le programme principal en tant que fragments séparés dans le cas où elles ne peuvent être mises en œuvre ni dans le langage de haut niveau utilisé ni à l'aide des procédures de service du système d'exploitation.

Un programme en langage assembleur ne peut s'exécuter que sur des ordinateurs de la même famille, tandis qu'un programme écrit dans un langage de haut niveau peut potentiellement s'exécuter sur des machines différentes.

L'alphabet du langage assembleur est composé de caractères ASCII.

Les nombres ne sont que des entiers. Distinguer:

Nombres binaires se terminant par la lettre B ;

Nombres décimaux se terminant par D ;

Nombres hexadécimaux se terminant par la lettre N.

RAM, registres, représentation des données

Pour une certaine série de MP, un langage de programmation individuel est utilisé - le langage d'assemblage.

Le langage d'assemblage occupe une position intermédiaire entre les codes machine et les langages de haut niveau. La programmation dans ce langage est plus facile. Un programme en langage assembleur utilise les capacités d'une machine particulière (plus précisément, MP) de manière plus rationnelle qu'un programme dans un langage de haut niveau (ce qui est plus facile pour un programmeur que pour un assembleur). Nous examinerons les principes de base de la programmation dans des langages orientés machine en utilisant le langage d'assemblage pour MP KR580VM80 à titre d'exemple. Pour la programmation dans le langage, une technique générale est utilisée. Des techniques spécifiques d'enregistrement de programmes sont liées à l'architecture et aux caractéristiques du système de commande du MP cible.

Modèle de logiciel système à microprocesseur basé sur MP KR580VM80

Le modèle de programme du MPS selon la figure 1

Mémoire des ports MP

S Z CA P C

Image 1

Du point de vue du programmeur, le KR580VM80 MP possède les registres suivants accessibles au programme.

UN– Registre d'accumulateur 8 bits. C'est le registre principal des MP. Toute opération effectuée dans l'ALU consiste à placer l'un des opérandes à traiter dans l'accumulateur. Le résultat de l'opération dans l'ALU est également généralement stocké dans A.

B, C, D, E, H, L– Registres à usage général 8 bits (RON). Mémoire intérieure député. Conçu pour stocker les informations traitées, ainsi que les résultats de l'opération. Lors du traitement de mots de 16 bits à partir des registres, des paires BC, DE, HL sont formées et le registre double est appelé la première lettre - B, D, H. Dans la paire de registres, le premier registre est le plus élevé. Les registres H, L, utilisés à la fois pour stocker des données et pour stocker des adresses 16 bits de cellules RAM, ont une propriété particulière.

Floride– registre d'indicateurs (registre de caractéristiques) Un registre de 8 bits qui stocke cinq caractéristiques du résultat d'opérations arithmétiques et logiques dans le MP. Format FL conforme à la photo

Bit C (CY - report) - report, mis à 1 s'il y avait un report à partir de l'ordre supérieur de l'octet lors de l'exécution d'opérations arithmétiques.

Bit P (parité) - parité, est mis à 1 si le nombre d'unités dans les bits du résultat est pair.

Le bit AC est un report supplémentaire, conçu pour stocker la valeur de report de la tétrade inférieure du résultat.

Bit Z (zéro) - mis à 1 si le résultat de l'opération est 0.

Le bit S (signe) est mis à 1 si le résultat est négatif et à 0 si le résultat est positif.

PS-- le pointeur de pile, un registre de 16 bits, est conçu pour stocker l'adresse de l'emplacement mémoire où le dernier octet entré sur la pile a été écrit.

RS– compteur de programme (program counter), registre de 16 bits, destiné à stocker l'adresse de la prochaine instruction exécutable. Le contenu du compteur de programme est automatiquement incrémenté de 1 immédiatement après l'extraction de l'octet d'instruction suivant.

Dans la zone de mémoire initiale de l'adresse 0000H - 07FF se trouve programme de contrôle et des programmes de démonstration. C'est la zone ROM.

0800 - 0AFF - zone d'adresse pour l'enregistrement des programmes à l'étude. (RAM).

0В00 - 0ВВ0 - zone d'adresse pour l'enregistrement des données. (RAM).

0BB0 est l'adresse de départ de la pile. (RAM).

Stack est une zone spécialement organisée de RAM conçue pour le stockage temporaire de données ou d'adresses. Le dernier numéro poussé sur la pile est le premier numéro sorti de la pile. Le pointeur de pile stocke l'adresse du dernier emplacement de pile où les informations sont stockées. Lorsqu'un sous-programme est appelé, l'adresse de retour au programme principal est automatiquement stockée sur la pile. En règle générale, au début de chaque sous-programme, le contenu de tous les registres impliqués dans son exécution est stocké sur la pile, et à la fin du sous-programme, il est restauré à partir de la pile.

Format de données et structure de commande du langage d'assemblage

La mémoire MP KR580VM80 est un tableau de mots de 8 bits appelés octets.Chaque octet a sa propre adresse de 16 bits qui détermine sa position dans la séquence des cellules mémoire. Le MP peut adresser 65536 octets de mémoire, qui peuvent contenir à la fois de la ROM et de la RAM.

Format de données

Les données sont stockées en mémoire sous forme de mots de 8 bits :

D7 D6 D5 D4 D3 D2 D1 D0

Le bit le moins significatif est le bit 0, le bit le plus significatif est le bit 7.

La commande est caractérisée par le format, c'est-à-dire le nombre de bits qui lui sont alloués, qui sont divisés octet par octet en certains champs fonctionnels.

Format de commande

Les commandes MP KR580VM80 ont un format à un, deux ou trois octets. Les instructions multi-octets doivent être placées dans des PL voisins. Le format de la commande dépend des spécificités de l'opération en cours d'exécution.

Le premier octet de la commande contient l'opcode écrit sous forme mnémonique.

Il définit le format de la commande et les actions qui doivent être effectuées par le MP sur les données lors de son exécution, ainsi que la méthode d'adressage, et peut également contenir des informations sur la localisation des données.

Les deuxième et troisième octets peuvent contenir des données à exploiter ou des adresses indiquant l'emplacement des données. Les données sur lesquelles les opérations sont effectuées sont appelées opérandes.

Format de commande à un octet selon la figure 2

Figure 4

Dans les instructions en langage assembleur, l'opcode a une forme abrégée d'écriture de mots anglais - une notation mnémonique. Les mnémoniques (du grec mnémonique - l'art de la mémorisation) facilitent la mémorisation des commandes en fonction de leur objectif fonctionnel.

Avant l'exécution, le programme source est traduit à l'aide d'un programme de traduction, appelé assembleur, dans le langage des combinaisons de codes - langage machine, sous cette forme il est placé dans la mémoire du MP puis utilisé lors de l'exécution de la commande.


Méthodes d'adressage

Tous les codes d'opérande (entrée et sortie) doivent être situés quelque part. Ils peuvent se trouver dans les registres internes du MP (le plus pratique et choix rapide). Ils peuvent être situés dans la mémoire système (l'option la plus courante). Enfin, ils peuvent être dans des périphériques d'E/S (cas le plus rare). L'emplacement des opérandes est déterminé par le code d'instruction. Exister différentes méthodes, avec lequel le code d'instruction peut déterminer où prendre l'opérande d'entrée et où placer l'opérande de sortie. Ces méthodes sont appelées méthodes d'adressage.

Pour MP KR580VM80, il existe les méthodes d'adressage suivantes :

Immédiat;

Enregistrer;

indirect;

Empiler.

Immédiat l'adressage suppose que l'opérande (entrée) est en mémoire immédiatement après le code d'instruction. L'opérande est généralement une constante qui doit être envoyée quelque part, ajoutée à quelque chose, etc. les données sont contenues dans les deuxième ou deuxième et troisième octets de la commande, avec l'octet de données bas dans le deuxième octet de commande et l'octet de données haut dans le troisième octet de commande.

Droit L'adressage (alias absolu) suppose que l'opérande (entrée ou sortie) est situé en mémoire à l'adresse dont le code est situé à l'intérieur du programme immédiatement après le code d'instruction. Utilisé dans les commandes à trois octets.

Enregistrer l'adressage suppose que l'opérande (entrée ou sortie) se trouve dans le registre MP interne. Utilisé dans les commandes à un seul octet

Indirect L'adressage (implicite) suppose que le registre interne du MP n'est pas l'opérande lui-même, mais son adresse en mémoire.

Empiler l'adressage suppose que la commande ne contient pas d'adresse. Adressage des emplacements mémoire par le contenu du registre SP 16 bits (pointeur de pile).

Système de commande

Le système de commande MP est une liste complète d'actions élémentaires que le MP est capable d'effectuer. Le MP contrôlé par ces commandes effectue des actions simples, telles que des opérations arithmétiques et logiques élémentaires, le transfert de données, la comparaison de deux valeurs, etc. Le nombre de commandes du MP KR580VM80 est de 78 (y compris les modifications 244).

Il existe les groupes de commandes suivants :

Transmission de données;

Arithmétique;

Casse-tête;

Commandes de saut ;

Commandes d'entrée-sortie, de contrôle et de travail avec la pile.


Symboles et abréviations utilisés pour décrire les commandes et écrire les programmes

Symbole Réduction
ADDR Adresse 16 bits
DONNÉES Données 8 bits
DONNÉES 16 Données 16 bits
PORT Adresse d'E/S 8 bits (périphériques d'E/S)
OCTET 2 Deuxième octet de commande
OCTET 3 Troisième octet de commande
R, R1, R2 Un des registres : A, B, C, D, E, H, L
PR L'une des paires de registres : B - définit une paire d'aéronefs ; D - définit une paire de DE ; H - spécifie une paire de HL
HR Premier registre de la paire
RL Deuxième registre de la paire
Λ Multiplication booléenne
V Addition booléenne
Addition modulo deux
M Cellule de mémoire dont l'adresse spécifie le contenu de la paire de registres HL, c'est-à-dire M = (HL)

1. Architecture du PC………………………………………………………………5

    1.1. Registres.

    1.1.1 Registres à usage général.

1.1.2. registres de segments

1.1.3 Registre des drapeaux

1.2. Organisation de la mémoire.

1.3. Représentation des données.

1.3.1 Types de données

1.3.2 Représentation des caractères et des chaînes

2. Énoncés du programme de l'Assemblée ……………………………………………

    1. Commandes en langage d'assemblage

2.2. Modes d'adressage et formats d'instruction machine

3. Pseudo-opérateurs ………………………………………………………….

3.1 Directives de définition des données

3.2 Structure du programme de montage

3.2.1 Segments de programme. assumer la directive

3.2.3 Directive de segmentation simplifiée

4. Assemblage et liaison du programme ………………………….

5. Commandes de transfert de données…………………………………………….

    5.1 Commandes générales

    5.2 Commandes de pile

5.3 Commandes E/S

5.4 Commandes de renvoi d'adresse

5.5 Commandes de transfert de drapeau

6. Commandes arithmétiques ……………………………………………………….

    6.1 Opérations arithmétiques sur des entiers binaires

6.1.1 Addition et soustraction

6.1.2 Commandes pour incrémenter et décrémenter le récepteur d'une unité

6.2 Multiplication et division

6.3 Changement de signe

7. Opérations logiques ………………………………………………….

8. Quarts de travail et quarts de travail cycliques …………………………………………

9. Opérations sur les chaînes …………………………………………………….

10. Logique et organisation des programmes ………………………………………

10.1 Sauts inconditionnels

10.2 Sauts conditionnels

10.4 Procédures en langage assembleur

10.5 Interruptions INT

10.6 Logiciel système

10.6.1.1 Lecture du clavier.

10.6.1.2 Affichage des caractères à l'écran

10.6.1.3 Fin des programmes.

10.6.2.1 Sélection des modes d'affichage

11. Mémoire disque ……………………………………………………………..

11.2 Tableau d'attribution des fichiers

11.3 E/S disque

11.3.1 Ecriture d'un fichier sur disque

11.3.1.1 Données ASCIIZ

11.3.1.2 Numéro de dossier

11.3.1.3 Création d'un fichier disque

11.3.2 Lecture d'un fichier disque

Introduction

Le langage assembleur est une représentation symbolique du langage machine. Tous les processus d'un ordinateur personnel (PC) au niveau matériel le plus bas sont pilotés uniquement par des commandes en langage machine (instructions). Il est impossible de résoudre réellement des problèmes liés au matériel (ou même, d'ailleurs, des problèmes liés au matériel, comme l'amélioration de la vitesse d'un programme), sans connaissances en assembleur.

L'assembleur est une forme pratique de commandes directement destinées aux composants PC et nécessite la connaissance des propriétés et des capacités du circuit intégré contenant ces composants, à savoir le microprocesseur du PC. Ainsi, le langage assembleur est directement lié à l'organisation interne du PC. Et ce n'est pas un hasard si presque tous les compilateurs de langages de haut niveau prennent en charge l'accès au niveau de programmation assembleur.

Un élément de la préparation d'un programmeur professionnel est nécessairement l'étude de l'assembleur. En effet, la programmation en langage assembleur nécessite une connaissance de l'architecture PC, ce qui vous permet de créer des programmes plus efficaces dans d'autres langages et de les combiner avec des programmes en langage assembleur.

Le manuel traite de la programmation en langage assembleur pour les ordinateurs basés sur des microprocesseurs Intel.

Ce tutoriel s'adresse à tous ceux qui s'intéressent à l'architecture du processeur et aux bases de la programmation en langage assembleur, en premier lieu aux développeurs d'un produit logiciel.

    Architecture PC.

L'architecture informatique est une représentation abstraite d'un ordinateur qui reflète sa structure, ses circuits et son organisation logique.

Tous les ordinateurs modernes ont des propriétés architecturales communes et individuelles. Les propriétés individuelles ne sont inhérentes qu'à un modèle informatique spécifique.

Le concept d'architecture informatique comprend:

    schéma fonctionnel d'un ordinateur ;

    des moyens et méthodes d'accès aux éléments du schéma synoptique d'un ordinateur ;

    ensemble et disponibilité des registres ;

    organisation et méthodes d'adressage;

    méthode de présentation et format des données informatiques;

    un jeu d'instructions machine informatique;

    formats d'instructions machine ;

    interrompre la manipulation.

Les principaux éléments du matériel informatique: unité centrale, clavier, périphériques d'affichage, lecteurs de disque, périphériques d'impression (imprimante) et divers moyens de communication. Unité système se compose de la carte mère, de l'alimentation et des connecteurs d'extension pour les cartes optionnelles. La carte mère contient le microprocesseur, la mémoire morte (ROM), RAM(RAM) et coprocesseur.

      Registres.

A l'intérieur du microprocesseur, les informations sont contenues dans un groupe de 32 registres (16 utilisateur, 16 système), plus ou moins disponibles à l'usage du programmeur. Étant donné que le manuel est consacré à la programmation du microprocesseur 8088-i486, il est plus logique de commencer ce sujet en discutant des registres internes du microprocesseur à la disposition de l'utilisateur.

Les registres utilisateur sont utilisés par le programmeur pour écrire des programmes. Ces registres comprennent :

    huit registres 32 bits (registres à usage général) EAX/AX/AH/AL, EBX/BX/BH/BL, ECX/CX/CH/CL, EDX/DX/DLH/DL, EBP/BP, ESI/SI, EDI/DI, ESP/SP ;

    six registres de segment de 16 bits : CS, DS, SS, ES, FS, GS ;

    registres d'état et de contrôle : registre d'indicateurs EFLAGS/FLAGS et registre de pointeur de commande EIP/IP.

Les parties d'un registre 32 bits sont indiquées par une barre oblique. Le préfixe E (Extended) indique l'utilisation d'un registre 32 bits. Pour travailler avec des octets, des registres avec les préfixes L (bas) et H (élevé) sont utilisés, par exemple, AL, CH - désignant les octets bas et haut des parties 16 bits des registres.

        Registres généraux.

EAX/AX/AH/AL (registre d'accumulateur) - batterie. Utilisé dans la multiplication et la division, dans les opérations d'E/S et dans certaines opérations sur les chaînes.

EBX/BX/BH/BL - registre de base(registre de base), souvent utilisé lors de l'adressage de données en mémoire.

ECX/CX/CH/CL - comptoir(registre de comptage), utilisé comme compteur du nombre de répétitions de boucle.

EDX/DX/DH/DL - registre de données(registre de données), utilisé pour stocker des données intermédiaires. Certaines commandes l'exigent.

Tous les registres de ce groupe permettent d'accéder à leurs parties "inférieures". Seules les parties inférieures de 16 et 8 bits de ces registres peuvent être utilisées pour l'auto-adressage. Les 16 bits supérieurs de ces registres ne sont pas disponibles en tant qu'objets indépendants.

Pour prendre en charge les commandes de traitement de chaîne qui permettent le traitement séquentiel de chaînes d'éléments d'une longueur de 32, 16 ou 8 bits, les éléments suivants sont utilisés :

ESI/SI (registre d'index source) - indice source. Contient l'adresse de l'élément source courant.

EDI/DI (registre d'index de distance) - indice destinataire(destinataire). Contient l'adresse actuelle dans la chaîne de destination.

L'architecture du microprocesseur au niveau matériel et logiciel prend en charge la structure des données - la pile. Pour travailler avec la pile, il existe des commandes spéciales et des registres spéciaux. Il convient de noter que la pile est remplie vers des adresses plus petites.

ESP/SP (registre de pointeur de pile) - enregistrer aiguille empiler. Contient un pointeur vers le haut de la pile dans le segment de pile actuel.

EBP/BP (registre de pointeur de base) – registre de pointeur de base de pile. Conçu pour organiser un accès aléatoire aux données à l'intérieur de la pile.

1.1.2. registres de segments

Le modèle logiciel du microprocesseur comporte six registres de segments : CS, SS, DS, ES, GS, FS. Leur existence est due aux spécificités de l'organisation et de l'utilisation de la RAM par les microprocesseurs Intel. Le matériel du microprocesseur prend en charge l'organisation structurelle du programme consistant en segments. Pour spécifier les segments disponibles dans ce moment registres de segments. Le microprocesseur prend en charge les types de segments suivants :

    segment de code. Contient des commandes de programme Pour accéder à ce segment, utilisez le registre CS (registre de segment de code) - registre de code de segment. Il contient l'adresse du segment d'instruction machine auquel le microprocesseur a accès.

    segments de données. Contient les données traitées par le programme. Pour accéder à ce segment, le registre DS (registre de segment de données) est utilisé - registre de données de segment, qui stocke l'adresse du segment de données du programme en cours.

    Segment de pile. Ce segment est une région de mémoire appelée la pile. Le microprocesseur organise la pile selon le principe - le premier "venu", le premier "parti". Pour accéder à la pile, le registre SS (registre de segment de pile) est utilisé - registre de segment de pile A contenant l'adresse du segment de pile.

    Segment de données supplémentaire. Les données à traiter peuvent se trouver dans trois segments de données supplémentaires. Par défaut, les données sont supposées se trouver dans le segment de données. Lors de l'utilisation de segments de données supplémentaires, leurs adresses doivent être spécifiées explicitement à l'aide de préfixes spéciaux de redéfinition de segment dans la commande. Les adresses des segments de données supplémentaires doivent être contenues dans les registres ES, GS, FS (registres de segments de données d'extension).

        Registres de contrôle et d'état

Le microprocesseur contient plusieurs registres qui contiennent des informations sur l'état à la fois du microprocesseur lui-même et du programme dont les instructions sont actuellement chargées dans le pipeline. Ce:

Registre de pointeur de commande EIP/IP ;

    Registre d'indicateurs EFLAGS/FLAGS.

À l'aide de ces registres, vous pouvez obtenir des informations sur les résultats de l'exécution de la commande et influencer l'état du microprocesseur lui-même.

EIP/IP (registre de pointeur d'instruction) - aiguille équipes. Le registre EIP/IP a une largeur de 32 ou 16 bits et contient le décalage de la prochaine instruction à exécuter par rapport au contenu du registre de segment CS dans le segment d'instruction courant. Ce registre n'est pas directement accessible, mais il est modifié par des instructions de saut.

EFLAGS/FLAGS (Registre des drapeaux) - enregistrer drapeaux. Profondeur de bits 32/16 bits. Les bits individuels de ce registre ont un objectif fonctionnel spécifique et sont appelés drapeaux. Un indicateur est un bit qui est défini sur 1 ("l'indicateur est défini") si une condition est remplie et sur 0 ("l'indicateur est effacé") dans le cas contraire. La partie inférieure de ce registre est complètement analogue au registre FLAGS du i8086.

1.1.3 Registre des drapeaux

Le registre de drapeau est de 32 bits et porte le nom EFLAGS (Fig. 1). Les bits individuels du registre ont un objectif fonctionnel spécifique et sont appelés drapeaux. Chacun d'eux se voit attribuer un nom spécifique (ZF, CF, etc.). Les 16 bits inférieurs de EFLAGS représentent le registre FLAGS 16 bits utilisé lors de l'exécution de programmes écrits pour les microprocesseurs i086 et i286.

Fig.1 Registre des drapeaux

Certains drapeaux sont appelés drapeaux de condition ; ils changent automatiquement lorsque les commandes sont exécutées et fixent certaines propriétés de leur résultat (par exemple, s'il est égal à zéro). D'autres drapeaux sont appelés drapeaux d'état ; ils changent du programme et influencent le comportement ultérieur du processeur (par exemple, ils bloquent les interruptions).

Indicateurs d'état :

CF (porte drapeau) - porter le drapeau. Il prend la valeur 1 si, lors de l'addition d'entiers, une unité de retenue est apparue qui ne "rentrée" pas dans la grille de bits, ou si, lors de la soustraction de nombres non signés, le premier d'entre eux était inférieur au second. Dans les commandes de décalage, le bit qui est hors réseau est entré dans le CF. CF corrige également les caractéristiques de l'instruction de multiplication.

OF (drapeau de débordement) indicateur de débordement. Il est mis à 1 si, lors de l'addition ou de la soustraction d'entiers avec un signe, le résultat a été obtenu, modulo dépassant la valeur autorisée (la mantisse a débordé et elle est "montée" dans le bit de signe).

ZF (drapeau zéro) drapeau zéro. Mis à 1 si le résultat de la commande est 0.

SF (drapeau de signe) - drapeau signe. Mis à 1 si l'opération sur les nombres signés donne un résultat négatif.

PF (drapeau de parité) - drapeau parité. Il est égal à 1 si le résultat de la commande suivante contient un nombre pair de uns binaires. Il n'est généralement pris en compte que lors des opérations d'E/S.

AF (drapeau de portage auxiliaire) - drapeau de portage supplémentaire. Corrige les fonctionnalités d'exécution d'opérations sur des nombres décimaux binaires.

Indicateurs d'état :

DF (drapeau de direction) drapeau de direction. Définit la direction de balayage des lignes dans les commandes de chaîne : avec DF=0, les lignes sont balayées "vers l'avant" (du début à la fin), avec DF=1 - dans la direction opposée.

IOPL (niveau de privilège d'entrée/sortie) - Niveau de privilège d'E/S. Utilisé dans le mode protégé du microprocesseur pour contrôler l'accès aux commandes d'E / S, en fonction du privilège de la tâche.

NT (tâche imbriquée) indicateur d'imbrication de tâches. Utilisé dans le mode protégé du microprocesseur pour enregistrer le fait qu'une tâche est imbriquée dans une autre.

Indicateur système :

SI (indicateur d'interruption) - indicateur d'interruption. Avec IF=0, le processeur cesse de répondre aux interruptions qui lui parviennent, avec IF=1, le blocage des interruptions est supprimé.

TF (drapeau de piège) indicateur de trace. Avec TF=1, après l'exécution de chaque instruction, le processeur fait une interruption (avec le numéro 1), qui peut être utilisée lors du débogage d'un programme pour le tracer.

RF (indicateur de reprise) drapeau de reprise. Utilisé lors de la gestion des interruptions des registres de débogage.

VM (mode 8086 virtuel) - indicateur virtuel 8086. 1 - le processeur fonctionne en mode virtuel 8086. 0 - le processeur fonctionne en mode réel ou protégé.

AC (vérification de l'alignement) - drapeau de contrôle d'alignement. Conçu pour permettre le contrôle de l'alignement lors de l'accès à la mémoire.

      Organisation de la mémoire.

La mémoire physique à laquelle le microprocesseur a accès est appelée mémoire de travail ( ou mémoire vive RAM). La RAM est une chaîne d'octets qui ont leur propre adresse unique (son numéro), appelée physique. La plage d'adresses physiques est de 0 à 4 Go. Le mécanisme de gestion de la mémoire est entièrement basé sur le matériel.

Le microprocesseur prend en charge plusieurs modèles d'utilisation de la RAM dans le matériel :

    modèle segmenté. Dans ce modèle, la mémoire du programme est divisée en zones de mémoire contiguës (segments) et le programme lui-même ne peut accéder qu'aux données qui se trouvent dans ces segments ;

    modèle de page. Dans ce cas, la RAM est considérée comme un ensemble de blocs d'une taille fixe de 4 Ko. L'application principale de ce modèle est liée à l'organisation mémoire virtuelle, ce qui permet aux programmes d'utiliser plus d'espace mémoire que la quantité de mémoire physique. Pour un microprocesseur Pentium, la taille de la mémoire virtuelle possible peut aller jusqu'à 4 To.

L'utilisation et la mise en œuvre de ces modèles dépendent du mode de fonctionnement du microprocesseur :

    Mode adresse réelle (mode réel). Le mode est similaire au fonctionnement du processeur i8086. Requis pour le fonctionnement des programmes conçus pour les premiers modèles de processeur.

    Mode protégé. Le mode protégé permet le multitâche traitement d'informations, la protection de la mémoire à l'aide d'un mécanisme de privilège à quatre niveaux et sa pagination.

    Mode virtuel 8086. Dans ce mode, il devient possible d'exécuter plusieurs programmes pour i8086. Dans ce cas, les programmes en mode réel peuvent fonctionner.

La segmentation est un mécanisme d'adressage qui assure l'existence de plusieurs espaces d'adressage indépendants. Un segment est un bloc de mémoire indépendant pris en charge par le matériel.

Chaque programme dans le cas général peut être composé d'un nombre quelconque de segments, mais il a un accès direct aux trois principaux : code, données et pile - et de un à trois segments de données supplémentaires. Le système d'exploitation place des segments de programme dans la RAM à certaines adresses physiques, puis place les valeurs de ces adresses dans les registres appropriés. A l'intérieur d'un segment, le programme accède linéairement aux adresses relatives au début du segment, c'est-à-dire en commençant à l'adresse 0 et en terminant à une adresse égale à la taille du segment. Adresse relative ou biais, que le microprocesseur utilise pour accéder aux données dans un segment est appelé efficace.

Formation d'une adresse physique en mode réel

En mode réel, la plage d'adresses physiques est de 0 à 1 Mo. La taille de segment maximale est de 64 Ko. Lorsqu'on fait référence à un adresse physique La RAM est déterminée par l'adresse du début du segment et le décalage dans le segment. L'adresse de début de segment est extraite du registre de segment correspondant. Dans ce cas, le registre de segment ne contient que les 16 bits supérieurs de l'adresse physique du début du segment. Les quatre bits inférieurs manquants de l'adresse de 20 bits sont obtenus en décalant la valeur du registre de segment vers la gauche de 4 bits. L'opération de décalage est effectuée dans le matériel. La valeur de 20 bits résultante est l'adresse physique réelle correspondant au début du segment. C'est adresse physique est spécifié comme une paire "segment:offset", où "segment" est les 16 premiers bits de l'adresse de début du segment de mémoire auquel appartient la cellule, et "offset" est l'adresse 16 bits de cette cellule, comptée à partir de le début de ce segment mémoire (la valeur 16*segment +offset donne l'adresse absolue de la cellule). Si, par exemple, la valeur 1234h est stockée dans le registre CS, alors le couple d'adresses 1234h:507h définit une adresse absolue égale à 16*1234h+507h = 12340h+507h = 12847h. Une telle paire est écrite sous la forme d'un mot double et (comme pour les nombres) sous une forme "inversée": le premier mot contient le décalage et le second - le segment, chacun de ces mots est à son tour représenté sous la forme "inversée" former. Par exemple, la paire 1234h:5678h s'écrirait comme ceci :| 78 | 56| 34 | 12|.

Ce mécanisme de formation d'une adresse physique vous permet de rendre le logiciel relocalisable, c'est-à-dire non dépendant d'adresses de téléchargement spécifiques dans la RAM.

La programmation au niveau des instructions machine est le niveau minimum auquel la programmation est possible. Le système d'instructions machine doit être suffisant pour mettre en œuvre les actions requises en envoyant des instructions au matériel informatique.

Chaque instruction machine se compose de deux parties :

  • salle d'opération - déterminer "que faire" ;
  • opérande - définissant les objets de traitement, "que faire avec".

L'instruction machine du microprocesseur, écrite en langage assembleur, est une seule ligne avec la forme syntaxique suivante :

étiquette commande/directive opérande(s) ;commentaires

Dans ce cas, un champ obligatoire dans une ligne est une commande ou une directive.

L'étiquette, la commande/directive et les opérandes (le cas échéant) sont séparés par au moins un espace ou un caractère de tabulation.

Si une commande ou une directive doit être poursuivie sur la ligne suivante, le caractère barre oblique inverse est utilisé : \.

Par défaut, le langage d'assemblage ne fait pas la distinction entre les lettres majuscules et minuscules dans les commandes ou les directives.

Exemples de lignes de code :

Comptedb 1 ;Nom, directive, un opérande
déplacer eax,0 ;Commande, deux opérandes
cbw ; Équipe

Mots clés

Étiqueter en langage assembleur peut contenir les caractères suivants :

  • toutes les lettres de l'alphabet latin;
  • chiffres de 0 à 9 ;
  • caractères spéciaux : _, @, $, ?.

Un point peut être utilisé comme premier caractère d'une étiquette, mais certains compilateurs déconseillent ce caractère. Les noms de langage d'assemblage réservés (directives, opérateurs, noms de commande) ne peuvent pas être utilisés comme étiquettes.

Le premier caractère de l'étiquette doit être une lettre ou un caractère spécial (pas un chiffre). Longueur maximaleétiquettes - 31 caractères. Toutes les étiquettes écrites sur une ligne qui ne contient pas de directive assembleur doivent se terminer par deux-points : .

Équipes

Équipe indique au traducteur quelle action le microprocesseur doit effectuer. Dans un segment de données, une commande (ou directive) définit un champ, un espace de travail ou une constante. Dans un segment de code, une instruction définit une action, telle qu'un déplacement (mov) ou un ajout (add).

directives

L'assembleur a un certain nombre d'opérateurs qui vous permettent de contrôler le processus d'assemblage et de génération d'une liste. Ces opérateurs sont appelés directives . Ils n'agissent que dans le processus d'assemblage du programme et, contrairement aux instructions, ne génèrent pas de codes machine.

opérandes

Opérande – un objet sur lequel une commande machine ou un opérateur en langage de programmation est exécuté.
Une instruction peut avoir un ou deux opérandes, ou aucun opérande du tout. Le nombre d'opérandes est spécifié implicitement par le code d'instruction.
Exemples:

  • Aucun opérande ret ;Retour
  • Un opérande inc ecx ;Incrémenter ecx
  • Deux opérandes ajoutent eax,12 ;Ajouter 12 à eax

L'étiquette, la commande (directive) et l'opérande ne doivent pas commencer à une position particulière dans la chaîne. Cependant, il est recommandé de les écrire dans une colonne pour une plus grande lisibilité du programme.

Les opérandes peuvent être

  • identifiants ;
  • chaînes de caractères entourées de guillemets simples ou doubles ;
  • entiers en binaire, octal, décimal ou hexadécimal.
Identifiants

Identifiants – des séquences de caractères valides utilisées pour désigner des objets de programme tels que des codes d'opération, des noms de variable et des noms d'étiquette.

Règles d'écriture des identifiants.

  • L'identifiant peut être un ou plusieurs caractères.
  • Comme caractères, vous pouvez utiliser des lettres de l'alphabet latin, des chiffres et quelques caractères spéciaux : _, ?, $, @.
  • Un identifiant ne peut pas commencer par un chiffre.
  • L'ID peut comporter jusqu'à 255 caractères.
  • Le traducteur accepte les 32 premiers caractères de l'identifiant et ignore le reste.
commentaires

Les commentaires sont séparés de la ligne exécutable par un caractère ; . Dans ce cas, tout ce qui est écrit après le caractère point-virgule et jusqu'à la fin de la ligne est un commentaire. L'utilisation de commentaires dans un programme améliore sa clarté, en particulier lorsque le but d'un ensemble d'instructions n'est pas clair. Le commentaire peut contenir n'importe quel caractère imprimable, y compris des espaces. Le commentaire peut s'étendre sur toute la ligne ou suivre la commande sur la même ligne.

Structure du programme d'assemblage

Un programme écrit en langage assembleur peut être constitué de plusieurs parties, appelées modules . Chaque module peut définir un ou plusieurs segments de données, de pile et de code. Tout programme complet en langage assembleur doit inclure un module principal, ou principal, à partir duquel son exécution commence. Un module peut contenir du code, des données et des segments de pile déclarés avec les directives appropriées. Avant de déclarer des segments, vous devez spécifier le modèle de mémoire à l'aide de la directive .MODEL.

Un exemple de programme "ne faisant rien" en langage assembleur :

686P
.MODÈLE PLAT, STDCALL
.DONNÉES
.CODE
COMMENCER:

RET
FIN DEBUT

Ce programme ne contient qu'une seule instruction du microprocesseur. Cette commande est RET . Il assure la fin correcte du programme. En général, cette commande permet de sortir d'une procédure.
Le reste du programme est lié au fonctionnement du traducteur.
.686P - Les commandes en mode protégé Pentium 6 (Pentium II) sont autorisées. Cette directive sélectionne le jeu d'instructions assembleur pris en charge en spécifiant le modèle de processeur. La lettre P à la fin de la directive indique au traducteur que le processeur fonctionne en mode protégé.
.MODEL FLAT, stdcall est un modèle à mémoire plate. Ce modèle de mémoire est utilisé en salle d'opération Système Windows. appel standard
.DATA est un segment de programme contenant des données.
.CODE est un bloc de programme contenant du code.
START est une étiquette. En assembleur, les étiquettes jouent un rôle important, ce qui ne peut être dit des langages modernes de haut niveau.
END START - la fin du programme et un message au traducteur indiquant que le programme doit être démarré à partir de l'étiquette START .
Chaque module doit contenir une directive END marquant la fin code source programmes. Toutes les lignes qui suivent la directive END sont ignorées. L'omission de la directive END génère une erreur.
L'étiquette après la directive END indique au compilateur le nom du module principal à partir duquel l'exécution du programme commence. Si le programme contient un module, l'étiquette après la directive END peut être omise.




Haut