Programme en langage assembleur. Caractéristiques générales du système de commande du langage Assembler pour IBM-PC (ensemble de commandes de base, méthodes de base d'adressage des opérandes). Structure du programme en langage Assembleur. Commandes en langage assembleur

informations généralesà propos du langage assembleur

Le langage d'assemblage symbolique peut éliminer en grande partie les inconvénients de la programmation en langage machine.

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

Les noms symboliques saisis lors de la programmation en langage assembleur reflètent généralement la sémantique du programme, et l'abréviation des commandes reflète leur fonction principale. Par exemple : PARAM - paramètre, TABLE - table, MASK - masque, ADD - addition, SUB - soustraction, etc. etc. De tels noms sont faciles à retenir pour un programmeur.

Pour programmer en langage assembleur, il est nécessaire de disposer d'outils complexes que pour programmer en langage machine : il faut des systèmes informatiques basés sur un micro-ordinateur ou un PC avec un ensemble périphériques(clavier alphanumérique, afficheur de caractères, lecteur flottant et dispositif d'impression), ainsi que des systèmes résidents ou à programmation croisée pour les types de microprocesseurs requis. Le langage assembleur 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, car chaque instruction du microprocesseur se voit attribuer un nom symbolique spécifique.

Les langages d'assemblage offrent une augmentation significative de la productivité des programmeurs par rapport aux langages machine tout en conservant la possibilité d'utiliser toutes les ressources matérielles logicielles disponibles du microprocesseur. Cela permet aux programmeurs qualifiés d'écrire des programmes pouvant être exécutés en moins de un bref délais et occupent moins de mémoire par rapport aux programmes créés dans un langage de haut niveau.

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

À l'aide du langage assembleur, le programmeur peut définir les paramètres suivants :

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

un format standard pour les lignes d'un programme écrit en langage assembleur ;

format pour indiquer de diverses façons variantes d'adressage et de commande ;

format pour spécifier des constantes de caractères et des constantes entières dans divers systèmes numériques ;

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

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

Pour les micro-ordinateurs construits sur la base des types de microprocesseurs les plus courants, il peut exister plusieurs variantes du langage d'assemblage, mais l'une d'elles est généralement largement utilisée dans la pratique - c'est ce qu'on appelle le langage d'assemblage standard.

La programmation au niveau de l'instruction machine est le niveau minimum auquel les programmes peuvent être écrits. Le système d'instructions machine doit être suffisant pour mettre en œuvre les actions requises en émettant des instructions au matériel informatique.

Chaque commande machine se compose de deux parties :

· salle d'opération – déterminer « quoi faire » ;

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

La commande machine du microprocesseur, écrite en langage assembleur, est une ligne avec la forme syntaxique suivante :

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

Dans ce cas, le champ obligatoire dans la 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 continuée sur la ligne suivante, le caractère barre oblique inverse est utilisé : \.

Par défaut, le langage assembleur ne fait pas la distinction entre les lettres majuscules et minuscules lors de l'écriture de commandes ou de directives.

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

déplacement eax, somme ; eax = somme

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

Adressage indirect a à son tour les types suivants :

· adressage de base indirect (registre);

· adressage de base indirect (registre) avec décalage ;

· adressage d'index indirect ;

· Adressage d'index de base indirect.

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

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

Introduction.

Langue dans laquelle il est écrit programme original, appelé entrée langue, et la langue dans laquelle il est traduit pour exécution par le processeur est les jours de congé langue. Le processus de conversion de la langue d'entrée en 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émissions : compilation et interprétation.

À compilation le programme source est d'abord entièrement traduit en un programme équivalent dans le langage de sortie, appelé objet programme puis exécuté. Ce processus est mis en œuvre à l'aide d'un spécial programmes, appelé compilateur. Un compilateur pour lequel le langage d'entrée est une forme symbolique de représentation 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 est confiée à 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 d'abord toutes les lignes. équipe 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 assembleur décrit ci-dessous est implémenté à l’aide de la compilation.

Caractéristiques de la langue.

Principales fonctionnalités de l'assembleur :

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

) des mnémoniques sont utilisés

Soustractions (

multiplications (

Divisions (

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

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

● la langue donne accès à tous les objets et les équipes. Les langages de haut niveau n'ont pas cette capacité. Par exemple, le langage assembleur vous permet de vérifier les bits du registre des drapeaux et le langage de haut niveau (par exemple,

) n'a pas cette capacité. A noter 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 assembleur, mais ont la syntaxe d'un langage de haut niveau ;

● langage assembleur 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, l’écriture et le débogage d’un programme en langage assembleur prennent beaucoup de temps. Malgré cela, le langage assembleur a reçu large utilisation en raison des circonstances suivantes :

● un programme écrit en langage assembleur est nettement plus petit et s'exécute beaucoup plus rapidement qu'un programme écrit en langage de haut niveau. Pour certaines applications, ces indicateurs jouent un rôle primordial, par exemple, de nombreux programmes système(y compris les compilateurs), programmes sur 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 est généralement impossible à faire 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 temps réel embarqués.

Dans la plupart des programmes, seul un petit pourcentage du code total est responsable d'un pourcentage important 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, on utilise à la fois l'assembleur et l'un des langages de haut niveau.

Format 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 réservée au champ d'étiquette. L'étiquette est un nom symbolique, ou un identifiant, adresses mémoire. C'est nécessaire pour que vous puissiez :

● effectuer une transition conditionnelle ou inconditionnelle vers la commande ;

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

Ces déclarations sont accompagnées d'une étiquette. Pour indiquer un nom, des lettres (majuscules) de l'alphabet anglais et des chiffres sont utilisés. Le nom doit avoir une lettre au début et un séparateur deux-points à la fin. L'étiquette deux-points peut être écrite sur une ligne séparée et l'opcode peut être écrit sur la ligne suivante de la colonne 2, ce qui simplifie le travail du compilateur. L'absence de deux points ne permet pas de distinguer un label d'un code opération s'ils sont situés sur des lignes distinctes.

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

Il ne doit pas y avoir de noms identiques dans le champ d'étiquette, puisque l'étiquette est associée aux adresses de commande. Si lors de l'exécution du programme il n'est pas nécessaire d'appeler une commande ou des données depuis la mémoire, alors le champ d'étiquette reste vide.

Champ du code d’opération.

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

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

), et pour sauvegarder le contenu du registre en mémoire - un mnémonique

). Dans les langages d'assemblage

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

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

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

Champ d'opérande.

Ici se trouve Informations Complémentaires, nécessaire pour effectuer l'opération. Dans le champ opérande des commandes de saut, l'adresse vers laquelle le saut doit être effectué est indiquée, ainsi que les adresses et les registres qui sont des opérandes pour la commande machine. A titre d'exemple, nous donnons des opérandes pouvant être utilisés pour les processeurs 8 bits

● des données numériques,

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

En conséquence, les systèmes de nombres binaires, octaux, hexadécimaux et décimaux (

Vous n'êtes pas obligé de l'écrire). Si le premier chiffre d'un nombre hexadécimal est A, B, C,

Ensuite, un 0 (zéro) insignifiant 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 numérique (par exemple, 10B - adresse d'enregistrement

en système binaire);

● les identifiants,

pour enregistrer des paires d'avions,

Les premières lettres sont B,

N ; pour une paire d'accumulateurs et de registre de fonctionnalités -

; pour le compteur de programme -

;pour le pointeur de pile -

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

(si 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 de l'identifiant M1 ;

● expressions,

qui sont construits en reliant les données discutées ci-dessus à l'aide d'opérateurs arithmétiques et logiques. Notez que la méthode de réservation de l'espace de données dépend de la version linguistique. Développeurs de langage d'assemblage pour

Définir le mot), puis entré plus tard Option alternative.

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

En version linguistique

utilisé

Définir une constante).

Les processeurs traitent des opérandes de différentes longueurs. 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 de 32 bits (type

); AX - pour 16 bits (type

et AN - pour 8 bits (type

● pour les processeurs

Des suffixes sont ajoutés à chaque code opération : suffixe

Pour le type

; suffixe ".B" pour le type

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

) et des mots dans un registre de 64 bits à l'aide d'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 aux humains. Ils peuvent être nécessaires pour modifier un programme qui, sans ces commentaires, peut être totalement incompréhensible, même pour les programmeurs expérimentés. Un commentaire commence par un symbole et est utilisé pour expliquer et documenter les programmes. Le caractère de départ d'un commentaire peut être :

● point-virgule (;) dans les langues destinées aux processeurs de l'entreprise

Point d'exclamation(!) dans des langues pour

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

Pseudo-commandes (directives).

En langage assembleur, il existe deux principaux types de commandes :

basique instructions qui sont l’équivalent du code machine du processeur. Ces commandes effectuent tous les traitements prévus par le programme ;

pseudo-commandes ou directives, conçu pour servir le processus de traduction d'un programme dans un langage de combinaison de codes. A titre d'exemple dans le tableau. 5.2.2 montre quelques pseudo-commandes de l'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 :

● écrivez la séquence de commandes requise chaque fois qu'elle apparaît. 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. Cette sortie a ses inconvénients : il faut à chaque fois exécuter une commande spéciale d'appel de procédure et une commande de retour, qui, si la séquence est courte et fréquemment utilisée, peuvent réduire considérablement 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 représentée comme une pseudo-commande destinée à retraduire un groupe de commandes souvent rencontrées dans un programme.

Une macro, ou macrocommande, se caractérise par trois aspects : la macrodéfinition, la macroinversion et la macroextension.

Définition des macros

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

La définition de la macro a la structure suivante :

Liste d'expressions ; Définition des macros

Dans la structure donnée de la macro-définition, trois parties peuvent être distinguées :

● titre

macro, y compris le nom

Pseudo-commande

et un ensemble de paramètres ;

● marqué de points corps macros ;

● équipe

l'obtention du diplôme

définitions de macros.

Le jeu de paramètres de définition de macro contient une liste de tous les paramètres donnés dans le champ d’opérande pour le groupe d’instructions sélectionné. Si ces paramètres ont été donnés plus tôt dans le programme, ils n'ont pas besoin d'être indiqués dans l'en-tête de définition de la macro.

Pour réassembler le groupe de commandes sélectionné, un appel composé du nom est utilisé

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

Lorsque l'assembleur rencontre une définition de macro pendant le processus de compilation, il la stocke dans la table de définition de macro. Lors d'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 est appelée macro-inversion(appel de macro), et en le remplaçant par le corps de la macro - expansion macro.

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

L'expansion des macros se produit pendant le processus d'assemblage, et non pendant l'exécution du programme. Les méthodes de manipulation des chaînes de caractères sont affectées à macro signifie.

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

● Lors du premier passage, toutes les définitions de macro sont conservées et les appels de macro sont développés. Dans ce cas, le programme d'origine 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 le corps de la macro ;

● la deuxième passe traite le programme résultant sans macros.

Macros avec paramètres.

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

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

● avec officiel paramètres. Lors du développement d'une macro, chaque paramètre formel apparaissant 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 contient deux séquences de commandes similaires, différant par le fait que la première échange P et

Et le deuxième

Le programme 2 comprend une macro avec deux paramètres formels P1 et P2. Lors du développement d'une macro, chaque caractère P1 dans le 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 l'appel de macro

le programme 2 est marqué : P,

Le premier paramètre réel,

Deuxième paramètre réel.

Programme 1

Programme 2

MOUVEMENT EBX,Q MOUVEMENT EAX,Pl

MOUVEMENT Q,EAX MOUVEMENT EBX,P2

MOV P, EBX MOV P2, EAX

Capacités étendues.

Examinons quelques fonctionnalités avancées du langage

Si une macro contenant une commande de saut conditionnel et une étiquette vers laquelle accéder est appelée deux fois ou plus, l'étiquette sera dupliquée (problème d'étiquette en double), ce qui provoquera une erreur. Par conséquent, chaque appel attribue une étiquette distincte comme paramètre (par le programmeur). En langue

le label est déclaré local (

) et grâce à des fonctionnalités avancées, l'assembleur génère automatiquement une étiquette différente à chaque fois que la macro est développée.

vous permet de définir des macros à l'intérieur d'autres macros. Cette fonctionnalité avancée est très utile en combinaison avec la liaison conditionnelle d'un programme. Considérons

SI TAILLE DES MOTS GT 16 M2 MACRO

La macro M2 peut être définie dans les deux parties de l'instruction

Cependant, la définition dépend du processeur sur lequel le programme est assemblé : 16 bits ou 32 bits. Si M1 n’est pas appelé, 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, pour éviter une boucle sans fin, la macro doit se passer un paramètre qui change à chaque expansion, et également vérifier ce paramètre et termine la récursion lorsque le paramètre atteint une certaine valeur.

Sur l'utilisation des moyens macro en assembleur.

Lors de l'utilisation de macros, l'assembleur doit être capable d'exécuter deux fonctions : enregistrer les définitions de macro Et élargir les défis macro.

Enregistrement des définitions de macro.

Tous les noms de macros 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 générale dans laquelle, avec les noms de macros, se trouvent toutes les instructions et directives machine.

Lorsque vous rencontrez une macro lors de l'assemblage est 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ù sera stocké le corps de la macro ;

● 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ée comme caractère de paramètre formel.

Extension des appels de 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 arrête temporairement de lire les données d'entrée du périphérique d'entrée et commence à lire le corps de la macro stocké. Les paramètres formels extraits du corps de la macro sont remplacés par des paramètres réels et fournis par l'appel. L'esperluette & avant les paramètres permet à l'assembleur de les reconnaître.

Malgré le fait qu'il existe de nombreuses versions d'assembleur, les processus d'assemblage ont des caractéristiques communes et sont similaires à bien des égards. Le fonctionnement d’un assembleur à deux passes est discuté ci-dessous.

Assembleur en deux passes.

Un programme est constitué d'un certain nombre d'instructions. Par conséquent, il semblerait que lors de l'assemblage, vous puissiez utiliser la séquence d'actions suivante :

● le traduire en langage machine ;

● transférer le code machine obtenu dans un fichier et la partie correspondante du listing dans un autre fichier ;

● répétez les procédures répertoriées jusqu'à ce que l'intégralité du programme soit traduite.

Cependant, cette approche n'est pas efficace. Un exemple est le soi-disant problème lien de transfert. Si la première instruction est un saut vers l'instruction P, située à la toute fin du programme, alors l'assembleur ne peut pas la traduire. Il doit d'abord déterminer l'adresse de l'opérateur P, et pour ce faire il doit lire l'intégralité du programme. Chaque lecture complète du programme source est appelée passage. Montrons comment vous pouvez résoudre le problème du lien d'analyse en utilisant deux passes :

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

● au premier passage, vous devriez convertir le programme sous une forme intermédiaire et enregistrez-le dans un tableau, puis effectuez le deuxième passage non pas selon le programme d'origine, mais selon le tableau. Cette méthode d'assemblage permet de gagner du temps, puisque la deuxième passe n'effectue pas d'opérations d'E/S.

Premier passage.

But de la première passe- construire une table de symboles. Comme indiqué ci-dessus, un autre objectif de la première passe est de conserver toutes les définitions de macro et d'étendre les appels au fur et à mesure qu'ils apparaissent. Par conséquent, la définition des symboles et l’expansion des macros s’effectuent en une seule passe. Le symbole peut être soit étiquette, ou signification, auquel un nom spécifique est attribué à l'aide de la directive -you :

;Valeur - taille du tampon

En attribuant une signification aux noms symboliques dans le champ d'étiquette de commande, l'assembleur spécifie essentiellement les adresses que chaque commande aura lors de l'exécution du programme. A cet effet, l'assembleur stocke pendant le processus d'assemblage compteur d'adresses d'instruction(

) comme variable spéciale. Au début du premier passage, 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 de programme indiquant la longueur des commandes et les valeurs du compteur. Au premier passage, les tables sont générées noms symboliques, directives Et codes d'opération, et si nécessaire littéral tableau. Un littéral est une constante pour laquelle l'assembleur réserve automatiquement de la mémoire. Notons immédiatement que les processeurs modernes contiennent des instructions avec des adresses immédiates, leurs assembleurs ne prennent donc pas en charge les littéraux.

Tableau des noms de symboles

contient un élément pour chaque nom (tableau 5.2.4). Chaque élément de la table des noms symboliques 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 réallocation de 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 directif.

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

Tableau des codes d'opération.

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

Deuxième passage.

But de la deuxième passe- création d'un programme objet et impression, si nécessaire, du protocole d'assemblage ; afficher les informations nécessaires à l'éditeur de liens pour lier les procédures assemblées à différents moments en un seul fichier exécutable.

Lors de la deuxième passe (comme lors de la première), les lignes contenant les instructions sont lues et traitées une par une. L'opérateur d'origine et l'opérateur de sortie qui en dérive en hexadécimal objet Le code peut être imprimé ou placé dans un tampon pour une impression ultérieure. Après avoir réinitialisé le compteur d'adresses de commande, la commande est appelée déclaration suivante.

Le programme source peut contenir des erreurs, par exemple :

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

● l'opcode est représenté par un nom invalide (en raison d'une faute de frappe), n'a pas assez d'opérandes ou a trop d'opérandes ;

● aucun opérateur

Certains assembleurs peuvent détecter un symbole non défini et le remplacer. Cependant, dans la plupart des cas, lorsqu'il rencontre une instruction d'erreur, 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 Bases de la programmation du processeur

À mesure que la durée du programme augmente, il devient de plus en plus difficile de mémoriser les codes des différentes opérations. Les mnémoniques fournissent une certaine aide à cet égard.

Le langage de codage de commandes symboliques est appelé assembleur.

Langage d'assemblage est un langage dans lequel chaque énoncé correspond exactement à une commande machine.

Assemblée appelé conversion d'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'incorporer des programmes de bibliothèque et générer des séquences d'instructions symboliques en spécifiant des paramètres en micro-équipes. Ce programme généralement situé dans la ROM ou entré dans la RAM à partir de certains supports externes.

Le langage assembleur possède plusieurs fonctionnalités qui le distinguent des langages de haut niveau :

1. Il s'agit d'une correspondance biunivoque entre les instructions du langage assembleur et les instructions machine.

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

Comprendre les bases de la programmation dans les langages orientés machine est utile pour :



Meilleure compréhension de l'architecture des PC et utilisation plus compétente 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 les programmes spécifiés dans le débogueur du programme DEBUG et en décompilant leur affichage en assembleur langue);

Compilation de programmes pour résoudre les problèmes les plus critiques (un programme écrit dans un langage orienté machine est généralement plus efficace - 30 à 60 % plus court et plus rapide des programmes obtenus grâce à la traduction à partir de langages de haut niveau)

Implémenter les procédures incluses dans le programme principal sous forme de fragments séparés dans le cas où elles ne peuvent être implémentées 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 une seule famille d'ordinateurs, tandis qu'un programme écrit dans un langage de haut niveau peut potentiellement s'exécuter sur différentes machines.

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

Les nombres ne sont que des entiers. Il y a:

Les nombres binaires se terminent par la lettre B ;

Nombres décimaux se terminant par la lettre D ;

Les nombres hexadécimaux se terminent par la lettre H.

RAM, registres, présentation des données

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

Le langage assembleur 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 plus efficacement les capacités d'une machine spécifique (plus précisément, un MP) qu'un programme en langage de haut niveau (qui est plus simple pour un programmeur qu'un assembleur). Regardons les principes de base de la programmation dans les langages orientés machine en utilisant l'exemple du langage assembleur pour le MP KR580VM80. Une méthodologie générale est utilisée pour programmer dans le langage. Les techniques techniques spécifiques d'enregistrement des programmes sont associées aux caractéristiques de l'architecture et du système de commande du MP cible.

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

Modèle logiciel du MPS selon la figure 1

Mémoire des ports MP

S Z A.C. P. C

Image 1

Du point de vue du programmeur, le MP KR580VM80 dispose des registres suivants accessibles par programme.

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

B, C, D, E, H, L– Registres à usage général (GPR) 8 bits. 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, les registres forment des paires BC, DE, HL et le double registre est appelé la première lettre - B, D, H. Dans une paire de registres, le plus élevé est le premier registre. Les registres H et L ont une propriété spéciale, utilisée à la fois pour stocker des données et pour stocker des adresses 16 bits de cellules RAM.

FL– registre de drapeaux (registre de signes) registre de 8 bits dans lequel sont stockés cinq signes du résultat des opérations arithmétiques et logiques effectuées dans le MP. Format FL conforme à l'image

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

Bit P (parité) – parité, définie sur 1 si le nombre de un dans les bits du résultat est pair.

Le chiffre AC est un report supplémentaire, conçu pour stocker la valeur de report de la tétrade d'ordre inférieur du résultat.

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

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, conçu pour stocker l'adresse de la cellule mémoire où a été écrit le dernier octet inséré sur la pile.

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

La zone mémoire initiale d'adresse 0000Н – 07FF contient le programme de contrôle et les 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'écriture des données. (RAM).

0ВВ0 – adresse de départ de la pile. (RAM).

Une pile est une zone de RAM spécialement organisée destinée au stockage temporaire de données ou d'adresses. Le dernier numéro écrit dans la pile est affiché en premier. Le pointeur de pile stocke l'adresse de la dernière cellule de pile dans laquelle les informations sont écrites. Lorsqu'un sous-programme est appelé, l'adresse de retour vers le 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 enregistré 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 assembleur

La mémoire du MP KR580VM80 est un tableau de mots de 8 bits appelés octets. Chaque octet possède sa propre adresse de 16 bits, qui détermine sa position dans la séquence de cellules mémoire. Le MP peut adresser 65 536 octets de mémoire, qui peuvent être contenus à la fois dans la ROM et dans la RAM.

Format des 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 de poids faible est le bit 0, le bit de poids fort est le bit 7.

Une commande est caractérisée par son 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 commandes multioctets doivent être placées dans des langues adjacentes. Le format de la commande dépend des spécificités de l'opération en cours.

Le premier octet de la commande contient le code d'opération, écrit sous forme mnémonique.

Il détermine le format de 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 l'emplacement des données.

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

Format de commande à un octet selon la figure 2

Figure 4

Dans les commandes en langage assembleur, le code d'opération 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 exécution, le programme source est traduit à l'aide d'un programme de traduction appelé assembleur vers le langage des combinaisons de codes - langage machine, sous cette forme il est placé dans la mémoire du MP et est ensuite 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 être localisés dans les registres internes du député (le plus pratique et option rapide). Ils peuvent être localisés dans mémoire système(l'option la plus courante). Enfin, ils peuvent être localisés dans des périphériques d'E/S (cas le plus rare). L'emplacement des opérandes est déterminé par le code 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 le MP KR580VM80, les méthodes d'adressage suivantes existent :

Direct;

Registre;

Indirect;

Empilé.

Direct l'adressage suppose que l'opérande (d'entrée) est situé 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 le deuxième ou le deuxième et le troisième octet de la commande, l'octet de données faible étant situé dans le deuxième octet de la commande, et l'octet de poids fort dans le troisième octet de commande.

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

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

Indirect L'adressage (implicite) suppose que le registre interne du MP ne contient 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 cellules mémoire à l'aide du contenu du registre SP 16 bits (pointeur de pile).

Système de commande

Le système de commandement MP est une liste complète des 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 (en tenant compte des modifications 244).

On distingue 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 pile.


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

Symbole Réduction
ADDR Adresse 16 bits
DONNÉES données 8 bits
DONNÉES 16 données 16 bits
PORT Adresse du périphérique d'E/S 8 bits
OCTET 2 Deuxième octet de la commande
OCTET 3 Troisième octet de commande
R, R1, R2 Un des registres : A, B, C, D, E, H, L
R.P. L'une des paires de registres : B - spécifie la paire BC ; D - spécifie une paire DE ; H – spécifie la paire HL
RH Premier registre du couple
R.L. Deuxième registre du couple
Λ Multiplication logique
V Ajout logique
Ajout modulo deux
M Une cellule 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. Présentation des données.

1.3.1 Types de données

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

2. Instructions de programme en assembleur ……………………………………

    1. Commandes en langage assembleur

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

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

3.1 Directives de définition des données

3.2 Structure d'un programme assembleur

3.2.1 Segments de programme. assumer la directive

3.2.3 Directive de segmentation simplifiée

4. Assemblage et composition 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 transfert d'adresse

5.5 Commandes de transfert de drapeau

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

    6.1 Opérations arithmétiques sur les 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. Changements et changements 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 Terminer les programmes.

10.6.2.1 Sélection des modes d'affichage

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

11.2 Tableau de répartition des fichiers

11.3 Opérations d'E/S disque

11.3.1 Écriture d'un fichier sur le 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 (instructions) en langage machine. Il est impossible de véritablement résoudre des problèmes liés au matériel (ou même d'ailleurs dépendants du matériel, comme l'augmentation de la vitesse d'un programme), sans connaissance en assembleur.

L'assembleur est une forme pratique de commandes directement pour les composants du 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 formation 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 à toute personne intéressée par l'architecture des processeurs et les bases de la programmation en langage Assembleur, principalement aux développeurs de produits logiciels.

    Architecture PC.

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

Tous les ordinateurs modernes possèdent des propriétés architecturales communes et individuelles. Les propriétés individuelles sont propres à un modèle informatique spécifique.

Le concept d'architecture informatique comprend :

    schéma fonctionnel informatique;

    des moyens et méthodes d'accès aux éléments du schéma bloc informatique ;

    ensemble et disponibilité des registres ;

    organisation et méthodes d'adressage ;

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

    un ensemble d'instructions machine informatique ;

    formats d'instructions machine ;

    gestion des interruptions.

Les principaux éléments du matériel informatique : unité centrale, clavier, dispositifs d'affichage, lecteurs de disque, dispositifs d'impression (imprimante) et divers équipements de communication. Unité système se compose d'une carte mère, d'une alimentation et de cellules d'extension pour des cartes supplémentaires. La carte système contient un microprocesseur, une mémoire morte (ROM), RAM(RAM) et coprocesseur.

      Registres.

À l'intérieur du microprocesseur, les informations sont contenues dans un groupe de 32 registres (16 utilisateurs, 16 système), à ​​un degré ou à un autre, disponibles pour être utilisés par le programmeur. Le manuel étant consacré à la programmation du microprocesseur 8088-i486, il est plus logique de commencer ce sujet par une discussion sur les registres internes du microprocesseur accessibles à 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 segments de 16 bits : CS, DS, SS, ES, FS, GS ;

    registres d'état et de contrôle : registre de drapeaux 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(haut) sont utilisés, par exemple AL, CH - désignant les octets bas et hauts des parties 16 bits des registres.

        Registres à usage général.

EAX/AX/AH/AL (registre 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é pour adresser des données en mémoire.

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

EDX/DX/DH/DL – registre de données(registre de données), utilisé pour stocker des données intermédiaires. Dans certaines équipes, son utilisation est obligatoire.

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înes 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 actuel.

EDI/DI (registre d’index de destination) – indice destinataire(destinataire). Contient l'adresse actuelle dans la ligne de destination.

Dans l'architecture du microprocesseur, une structure de données – une pile – est prise en charge au niveau matériel et logiciel. Il existe des instructions spéciales et des registres spéciaux pour travailler avec la pile. Il convient de noter que la pile est remplie vers des adresses plus petites.

ESP/SP (registre de pointeur de pile) – registre 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 l'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 à l'organisation et à l'utilisation spécifiques de la RAM par les microprocesseurs Intel. Le matériel du microprocesseur prend en charge l'organisation structurelle du programme composé de segments. Pour indiquer les segments disponibles dans ce moment les registres de segments sont prévus. Le microprocesseur prend en charge les types de segments suivants :

    Segment de code. Contient les commandes du 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.

    Segment de données. Contient les données traitées par le programme. Pour accéder à ce segment, utilisez le registre DS (data segment register) - registre de données de segment, qui stocke l'adresse du segment de données du programme actuel.

    Segment de pile. Ce segment est une zone de mémoire appelée la pile. Le microprocesseur organise la pile selon le principe : premier « entré », premier « sorti ». Pour accéder à la pile, utilisez le registre SS (stack segment register) - registre de segments de pile, contenant l'adresse du segment de pile.

    Segment de données supplémentaire. Les données traitées peuvent être localisées 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 remplacement 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 contenant des informations sur l'état du microprocesseur lui-même et du programme dont les commandes sont actuellement chargées dans le pipeline. Ce:

Registre de pointeur d'instruction EIP/IP ;

    registre des drapeaux EFLAGS/FLAGS.

À l'aide de ces registres, vous pouvez obtenir des informations sur les résultats de l'exécution des commandes 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 actuel. Ce registre n'est pas directement accessible, mais peut être modifié à l'aide d'instructions de saut.

EFLAGS/FLAGS (registre des drapeaux) – registre drapeaux. Taille 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 prend la valeur 1 (« indicateur défini ») si une condition est remplie, et la valeur 0 (« indicateur effacé ») dans le cas contraire. La partie basse de ce registre est complètement similaire au registre FLAGS pour i8086.

1.1.3 Registre des drapeaux

Le registre des drapeaux est de 32 bits et s'appelle 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 d'EFLAGS représentent le registre d'indicateurs FLAGS de 16 bits utilisé lors de l'exécution de programmes écrits pour les microprocesseurs i086 et i286.

Fig.1 Registre des drapeaux

Certains indicateurs sont communément appelés indicateurs de condition ; ils changent automatiquement lorsque les commandes sont exécutées et enregistrent 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 de condition :

CF (porter le drapeau) - porter le drapeau. Prend la valeur 1 si, lors de l'ajout d'entiers, une unité de retenue est apparue qui ne « rentrait » 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 se trouve en dehors de la grille de bits est entré dans CF. CF capture également les caractéristiques de l'instruction de multiplication.

OF (drapeau de débordement) - drapeau de débordement. Mis à 1 si, lors de l'ajout ou de la soustraction d'entiers signés, le résultat est un résultat qui dépasse la valeur autorisée en valeur absolue (la mantisse a débordé et elle a « grimpé » dans le chiffre du signe).

ZF (drapeau zéro) - zéro drapeau. Défini sur 1 si le résultat de la commande est 0.

SF (drapeau SIgn) - drapeau signe. Défini sur 1 si une opération sur des nombres signés produit un résultat négatif.

PF (drapeau de parité) - drapeau parité. Égal à 1 si le résultat de la commande suivante contient un nombre pair de uns binaires. Généralement pris en compte uniquement pour les opérations d'E/S.

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

Drapeaux d'État :

DF (drapeau de direction) - drapeau de direction. Définit la direction d'affichage des lignes dans les commandes de ligne : lorsque DF=0, les lignes sont visualisées « vers l'avant » (du début à la fin), lorsque DF=1 - dans la direction opposée.

IOPL (niveau de privilège d'entrée/sortie) – Niveau de privilège E/S. Utilisé en mode protégé de fonctionnement 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é en mode protégé de fonctionnement du microprocesseur pour enregistrer le fait qu'une tâche est imbriquée dans une autre.

Indicateur système :

SI (indicateur d'interruption) - drapeau d'interruption. Lorsque IF=0, le processeur cesse de répondre aux interruptions entrantes ; lorsque IF=1, le blocage des interruptions est supprimé.

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

RF (drapeau de reprise) – reprendre le drapeau. Utilisé lors du traitement des interruptions des registres de débogage.

VM (mode virtuel 8086) – drapeau virtuel 8086. 1 processeur fonctionne en mode virtuel 8086. 0 processeur fonctionne en mode réel ou protégé.

AC (vérification d'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 RAM ( 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 des valeurs d'adresse physique est de 0 à 4 Go. Le mécanisme de gestion de la mémoire est entièrement matériel.

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

    modèle segmenté. Dans ce modèle, la mémoire des programmes 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 situées 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. La principale application de ce modèle est liée à l'organisation mémoire virtuelle, qui permet aux programmes d'utiliser plus d'espace mémoire que la mémoire physique. Pour un microprocesseur Pentium, la taille de la mémoire virtuelle possible peut atteindre 4 To.

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

    Mode d'adresse réelle (mode réel). Le mode est similaire au fonctionnement du processeur i8086. Nécessaire au fonctionnement des programmes développés pour les premiers modèles de processeurs.

    Mode protégé. Le mode protégé vous permet d'effectuer plusieurs tâches à la fois traitement d'informations, protection de la mémoire à l'aide d'un mécanisme de privilèges à quatre niveaux et de son organisation de pagination.

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

La segmentation est un mécanisme d'adressage qui garantit 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 peut généralement être constitué d'un nombre quelconque de segments, mais il a un accès direct à trois segments principaux : code, données et pile - et à un à trois segments de données supplémentaires. Le système d'exploitation place des segments de programme dans la RAM à des adresses physiques spécifiques, puis place les valeurs de ces adresses dans les registres appropriés. Au sein d'un segment, le programme accède aux adresses relatives au début du segment de manière linéaire, c'est-à-dire en commençant par l'adresse 0 et en terminant par une adresse égale à la taille du segment. Adresse relative ou biais, que le microprocesseur utilise pour accéder aux données d'un segment est appelé efficace.

Formation d'une adresse physique en mode réel

En mode réel, la plage de modification de l'adresse physique est de 0 à 1 Mo. La taille maximale des segments est de 64 Ko. Lorsque vous contactez un particulier adresse physique La RAM est déterminée par l'adresse du début du segment et le décalage au sein du 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 de poids fort de l'adresse physique de début de segment. Les quatre bits faibles 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 matériellement. La valeur de 20 bits résultante est la véritable adresse physique 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 de 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 le registre CS stocke la valeur 1234h, alors le couple d'adresses 1234h:507h définit une adresse absolue égale à 16*1234h+507h =12340h+507h = 12847h. Une telle paire s'écrit comme un double mot, et (comme pour les nombres) sous une forme « inversée » : le premier mot contient un décalage, et le second - un segment, et chacun de ces mots, à son tour, est présenté dans un forme « inversée ». Par exemple, la paire 1234h:5678h s'écrirait ainsi :| 78 | 56| 34 | 12|.

Ce mécanisme de génération d'adresse physique permet de rendre le logiciel délocalisable, c'est à dire indépendant des adresses spécifiques de chargement en RAM.

La programmation au niveau de l'instruction machine est le niveau minimum auquel les programmes peuvent être écrits. Le système d'instructions machine doit être suffisant pour mettre en œuvre les actions requises en émettant des instructions au matériel informatique.

Chaque commande machine se compose de deux parties :

  • opérationnel - déterminer « quoi faire » ;
  • opérande - définissant les objets de traitement, « que faire avec ».

La commande machine du microprocesseur, écrite en langage assembleur, est une ligne avec la forme syntaxique suivante :

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

Dans ce cas, le champ obligatoire dans la 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 continuée sur la ligne suivante, le caractère barre oblique inverse est utilisé : \.

Par défaut, le langage assembleur ne fait pas la distinction entre les lettres majuscules et minuscules lors de l'écriture de commandes ou de directives.

Exemples de lignes de code :

Compter la base de données 1 ;Nom, directive, un opérande
déplacement eax,0 ;Commande, deux opérandes
cbw; Équipe

Mots clés

Étiquette en langage assembleur peut contenir les symboles suivants :

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

Un point peut être utilisé comme premier caractère d'une étiquette, mais certains compilateurs ne recommandent pas d'utiliser ce caractère. Les noms d'assembleur réservés (directives, opérateurs, noms de commandes) 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 (mais pas un chiffre). Longueur maximale balises – 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 commande spécifie une action, telle que déplacer (mov) ou ajouter (ajouter).

Directives

L'assembleur dispose d'un certain nombre d'opérateurs qui vous permettent de contrôler le processus d'assemblage et de listage. Ces opérateurs sont appelés directive . Elles n'agissent que pendant le processus d'assemblage du programme et, contrairement aux commandes, ne génèrent pas de code machine.

Opérandes

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

  • Aucun opérande ret ;Retour
  • Un opérande inc ecx ; Augmenter ecx
  • Deux opérandes ajoutent eax,12 ;Ajoutent 12 à eax

L'étiquette, la commande (directive) et l'opérande ne doivent pas nécessairement commencer à une position particulière dans la ligne. Il est toutefois recommandé de les écrire dans une colonne pour faciliter la lecture du programme.

Les opérandes peuvent être

  • identifiants;
  • chaînes de caractères entourées de guillemets simples ou doubles ;
  • entiers dans les systèmes numériques binaires, octaux, décimaux ou hexadécimaux.
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 variables et des noms d'étiquettes.

Règles d'enregistrement des identifiants.

  • L'identifiant peut être constitué d'un ou plusieurs caractères.
  • Comme symboles, 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 caractère numérique.
  • La longueur de l'identifiant peut aller 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 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 de commandes n'est pas clair. Le commentaire peut contenir n'importe quel caractère imprimable, y compris des espaces. Un commentaire peut s'étendre sur toute la ligne ou suivre une 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 avoir un ou plusieurs segments de données, de pile et de code définis. Tout programme assembleur complet doit inclure un module principal, ou principal, à partir duquel son exécution commence. Un module peut contenir des segments de code, des segments de données et des segments de pile, déclarés à l'aide des 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 rien faire » en langage assembleur :

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

RETRAIT
FIN DÉBUT

Ce programme ne contient qu'une seule commande du microprocesseur. Cette commande est RET. Il garantit que le programme se termine correctement. En général, cette commande permet de quitter une procédure.
La suite du programme concerne le fonctionnement du traducteur.
.686P - Les commandes en mode protégé du Pentium 6 (Pentium II) sont autorisées. Cette directive sélectionne l'ensemble d'instructions assembleur pris en charge, indiquant le modèle de processeur. La lettre P indiquée à la fin de la directive informe le traducteur que le processeur fonctionne en mode protégé.
.MODEL FLAT, stdcall - modèle de 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.
DÉBUT - étiquette. En assembleur, les balises jouent un rôle important, ce qui n'est pas le cas des langages modernes de haut niveau.
END START - la fin du programme et un message au traducteur indiquant que l'exécution du programme doit commencer par l'étiquette START.
Chaque module doit contenir une directive END pour marquer la fin code source programmes. Toutes les lignes qui suivent la directive END sont ignorées. Si vous omettez la directive END, une erreur est générée.
L'étiquette spécifiée après la directive END indique au traducteur 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