Instructions en langage d'assemblage. Résumé : Plan : Préface

UNIVERSITÉ NATIONALE D'OUZBÉKISTAN DU NOM DE MIRZO ULUGBEK

FACULTÉ DES TECHNOLOGIES INFORMATIQUES

Sur le sujet : Analyse sémantique d'un fichier EXE.

Complété:

Tachkent 2003.

Préface.

Langage d'assemblage et structure d'instructions.

Structure du fichier EXE (analyse sémantique).

Structure d'un fichier COM.

Comment le virus fonctionne et se propage.

Désassembleur.

Programmes.

Avant-propos

Le métier de programmeur est incroyable et unique. A notre époque, la science et la vie ne peuvent être imaginées sans dernière technologie. Tout ce qui est lié à l'activité humaine n'est pas complet sans l'informatique. Et cela contribue à son développement élevé et à sa perfection. Bien que le développement des ordinateurs personnels ait commencé il n'y a pas si longtemps, mais pendant ce temps, des étapes colossales ont été franchies dans les produits logiciels et plus encore. pendant longtemps ces produits seront largement utilisés. Le domaine des connaissances liées à l'informatique a explosé, tout comme la technologie qui s'y rapporte. Si on ne prend pas en considération le côté commercial, alors on peut dire que les étrangers dans ce domaine activité professionnelle non. Beaucoup sont engagés dans le développement de programmes sans but lucratif ou lucratif, mais de leur plein gré, par passion. Bien sûr, cela ne devrait pas affecter la qualité du programme, et dans ce secteur, pour ainsi dire, il existe une concurrence et une demande de performances de qualité, de travail stable et répondant à toutes les exigences de notre époque. Ici, il convient également de noter l'apparition des microprocesseurs dans les années 60, qui sont venus remplacer un grand nombre de jeux de lampes. Certaines variétés de microprocesseurs sont très différentes les unes des autres. Ces microprocesseurs diffèrent les uns des autres en termes de capacité en bits et de commandes système intégrées. Les plus courants sont : Intel, IBM, Celeron, AMD, etc. Tous ces processeurs sont liés à l'architecture avancée des processeurs Intel. La diffusion des micro-ordinateurs a provoqué une refonte des attitudes envers le langage d'assemblage pour deux raisons principales. Premièrement, les programmes écrits en langage d'assemblage nécessitent beaucoup moins de mémoire et d'exécution. Deuxièmement, la connaissance du langage d'assemblage et du code machine qui en résulte donne une compréhension de l'architecture de la machine, ce qui n'est guère fourni lorsque l'on travaille dans un langage de haut niveau. Bien que la plupart des professionnels du logiciel développent dans des langages de haut niveau tels que Pascal, C ou Delphi, qui est plus facile à écrire des programmes, le plus puissant et le plus efficace Logiciel entièrement ou partiellement écrit en langage assembleur. Les langages de haut niveau ont été conçus pour éviter des caractéristiques techniques ordinateurs spécifiques. Et le langage d'assemblage, à son tour, est conçu pour les spécificités spécifiques du processeur. Par conséquent, afin d'écrire un programme en langage assembleur pour un ordinateur particulier, il faut connaître son architecture. De nos jours, la vue de la principale produit logiciel est un fichier EXE. Compte tenu des aspects positifs de cela, l'auteur du programme peut être sûr de son inviolabilité. Mais souvent c'est loin d'être le cas. Il y a aussi un désassembleur. À l'aide d'un désassembleur, vous pouvez trouver les interruptions et les codes de programme. Il ne sera pas difficile pour une personne qui maîtrise bien l'assembleur de refaire tout le programme à son goût. C'est peut-être de là que vient le problème le plus insoluble - le virus. Pourquoi les gens écrivent-ils un virus ? Certains posent cette question avec surprise, d'autres avec colère, mais néanmoins il y a encore des gens qui s'intéressent à cette tâche non pas dans l'optique de causer du tort, mais par intérêt pour la programmation système. Les virus sont écrits pour diverses raisons. Certains aiment les appels système, d'autres perfectionnent leurs connaissances en assembleur. Je vais essayer d'expliquer tout cela dans ma dissertation. Il indique également non seulement la structure du fichier EXE, mais également le langage d'assemblage.

^ Langage d'assemblage.

Il est intéressant de suivre, depuis l'apparition des premiers ordinateurs jusqu'à nos jours, la transformation des idées sur le langage d'assemblage chez les programmeurs.

Il était une fois, l'assembleur était un langage sans savoir lequel il était impossible de faire faire quoi que ce soit d'utile à un ordinateur. Peu à peu, la situation a changé. Des moyens de communication plus pratiques avec un ordinateur sont apparus. Mais, contrairement à d'autres langages, l'assembleur n'est pas mort, de plus, il ne pouvait pas le faire en principe. Pourquoi? A la recherche d'une réponse, nous allons essayer de comprendre ce qu'est le langage d'assemblage en général.

En bref, le langage d'assemblage est une représentation symbolique du langage machine. Tous les processus de la machine au niveau matériel le plus bas ne sont pilotés que par des commandes (instructions) du langage machine. Il en ressort clairement que, malgré le nom commun, le langage d'assemblage de chaque type d'ordinateur est différent. Ceci s'applique également apparence programmes écrits en assembleur, et les idées dont ce langage est le reflet.

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.

Un programmeur ou tout autre utilisateur peut utiliser n'importe quel outil de haut niveau, jusqu'aux programmes de construction de mondes virtuels, et peut-être même ne pas soupçonner que l'ordinateur exécute réellement non pas les commandes du langage dans lequel son programme est écrit, mais leur représentation transformée sous la forme de séquences ennuyeuses et ternes de commandes d'un langage complètement différent - le langage machine. Imaginons maintenant qu'un tel utilisateur ait un problème non standard ou que quelque chose se soit mal passé. Par exemple, son programme doit fonctionner avec un appareil inhabituel ou effectuer d'autres actions nécessitant une connaissance des principes du matériel informatique. Peu importe à quel point un programmeur est intelligent, peu importe la qualité du langage dans lequel il a écrit son merveilleux programme, il ne peut pas se passer de connaissances en assembleur. Et ce n'est pas un hasard si presque tous les compilateurs de langages de haut niveau contiennent des moyens de connecter leurs modules avec des modules en assembleur ou prennent en charge l'accès au niveau de programmation assembleur.

Bien sûr, le temps des wagons informatiques est déjà révolu. Comme le dit le dicton, vous ne pouvez pas embrasser l'immensité. Mais il y a quelque chose en commun, une sorte de fondation sur laquelle repose toute formation sérieuse en informatique. Il s'agit de connaissances sur les principes de fonctionnement de l'ordinateur, son architecture et son langage d'assemblage en tant que reflet et incarnation de ces connaissances.

Un ordinateur moderne type (i486 ou Pentium) comprend les composants suivants (Figure 1).

Riz. 1. Ordinateur et périphériques

Riz. 2. Schéma fonctionnel ordinateur personnel

Sur la figure (Figure 1), on peut voir que l'ordinateur est composé de plusieurs périphériques physiques, chacun étant connecté à une unité, appelée unité système. Logiquement, il est clair qu'il joue le rôle d'un dispositif de coordination. Jetons un coup d'oeil à l'intérieur bloc système(pas besoin d'essayer de pénétrer à l'intérieur du moniteur - il n'y a rien d'intéressant là-bas, en plus c'est dangereux): nous ouvrons le boîtier et voyons des cartes, des blocs, des fils de connexion. Pour comprendre leur fonctionnalité, regardons diagramme ordinateur typique (Fig. 2). Il ne prétend pas à une exactitude absolue et vise uniquement à montrer le but, l'interconnexion et la composition typique des éléments d'un ordinateur personnel moderne.

Examinons le schéma de la Fig. 2 dans un style peu conventionnel.
C'est dans la nature humaine de rencontrer quelque chose de nouveau, de chercher des associations qui peuvent l'aider à connaître l'inconnu. Quelles associations l'ordinateur évoque-t-il ? Pour moi, par exemple, l'ordinateur est souvent associé à la personne elle-même. Pourquoi?

Une personne créant un ordinateur quelque part au plus profond de lui-même pensait créer quelque chose de semblable à lui-même. L'ordinateur a des organes pour recevoir des informations du monde extérieur - c'est un clavier, une souris, des lecteurs sur disques magnétiques. Sur la fig. 2 ces organes sont situés à droite des bus système. L'ordinateur a des organes qui "digèrent" les informations reçues - c'est le processeur central et RAM. Et, enfin, l'ordinateur a des organes de la parole qui donnent les résultats du traitement. Ce sont aussi quelques-uns des appareils sur la droite.

Ordinateurs modernes, bien sûr, loin d'être humain. Ils peuvent être comparés à des êtres interagissant avec le monde extérieur au niveau d'un ensemble large mais limité de réflexes inconditionnés.
Cet ensemble de réflexes forme un système d'instructions machine. Quel que soit le niveau de communication avec un ordinateur, tout se résume en fin de compte à une séquence ennuyeuse et monotone d'instructions machine.
Chaque commande de la machine est une sorte de stimulus pour l'excitation de tel ou tel réflexe inconditionné. La réaction à ce stimulus est toujours sans ambiguïté et est « câblée » dans le bloc de microcommandes sous la forme d'un microprogramme. Ce microprogramme met en oeuvre les actions pour mettre en oeuvre la commande machine, mais déjà au niveau des signaux appliqués à certains circuits logiques informatiques, commandant ainsi divers sous-systèmes informatiques. C'est ce qu'on appelle le principe du contrôle des microprogrammes.

Poursuivant l'analogie avec une personne, nous notons que pour qu'un ordinateur mange correctement, de nombreux systèmes d'exploitation, des compilateurs pour des centaines de langages de programmation, etc. ont été inventés. Mais tous ne sont en fait qu'un plat sur lequel la nourriture (programmes) est livrée selon certaines règles gastriques (ordinateur). Seul l'estomac d'un ordinateur aime les aliments diététiques et monotones - donnez-lui des informations structurées, sous la forme de séquences strictement organisées de zéros et de uns, dont les combinaisons constituent le langage machine.

Ainsi, étant extérieurement polyglotte, l'ordinateur ne comprend qu'un seul langage - le langage des instructions de la machine. Bien sûr, pour communiquer et travailler avec un ordinateur, il n'est pas nécessaire de connaître ce langage, mais presque tout programmeur professionnel est tôt ou tard confronté à la nécessité de l'apprendre. Heureusement, le programmeur n'a pas à essayer de comprendre la signification des différentes combinaisons. nombres binaires, comme dans les années 50, les programmeurs ont commencé à utiliser un analogue symbolique du langage machine pour la programmation, qu'ils ont appelé langage d'assemblage. Ce langage reflète fidèlement toutes les caractéristiques du langage machine. C'est pourquoi, contrairement aux langages de haut niveau, le langage d'assemblage est différent pour chaque type d'ordinateur.

De ce qui précède, on peut conclure que, le langage d'assemblage de l'ordinateur étant "natif", le programme le plus efficace ne peut être écrit que dans celui-ci (à condition qu'il soit écrit par un programmeur qualifié). Il y a un petit "mais" ici : c'est un processus très laborieux qui demande beaucoup d'attention et d'expérience pratique. Par conséquent, en réalité, l'assembleur écrit principalement des programmes qui devraient fournir travail efficace avec du matériel. Parfois, des parties critiques du programme en termes de temps d'exécution ou de consommation de mémoire sont écrites en assembleur. Par la suite, ils sont réalisés sous forme de sous-programmes et combinés avec du code dans un langage de haut niveau.

Il est logique de commencer à apprendre le langage d'assemblage de n'importe quel ordinateur uniquement après avoir découvert quelle partie de l'ordinateur est laissée visible et disponible pour la programmation dans ce langage. C'est ce qu'on appelle le modèle de programme informatique, dont une partie est le modèle de programme du microprocesseur, qui contient 32 registres qui sont plus ou moins disponibles pour être utilisés par le programmeur.

Ces registres peuvent être divisés en deux grands groupes :

^ 16 registres personnalisés ;

16 registres système.

Les programmes en langage d'assemblage utilisent très fortement les registres. La plupart des registres ont un objectif fonctionnel spécifique.

Comme leur nom l'indique, les registres d'utilisateurs sont appelés car le programmeur peut les utiliser lors de l'écriture de ses programmes. Ces registres comprennent (Fig. 3) :

Huit registres 32 bits pouvant être utilisés par les programmeurs pour stocker des données et des adresses (également appelés registres) usage général(RON)):

registres à six segments : cs, ds, ss, es, fs, gs ;

registres d'état et de contrôle :

Les drapeaux enregistrent les eflags/drapeaux ;

registre de pointeur de commande eip/ip.

Riz. 3. Registres d'utilisateurs des microprocesseurs i486 et Pentium

Pourquoi beaucoup de ces registres sont-ils affichés avec une barre oblique ? Non, ce ne sont pas des registres différents - ils font partie d'un grand registre 32 bits. Ils peuvent être utilisés dans le programme en tant qu'objets séparés. Cela a été fait pour garantir l'opérabilité des programmes écrits pour les modèles de microprocesseurs 16 bits plus récents d'Intel, à commencer par le i8086. Les microprocesseurs i486 et Pentium ont principalement des registres 32 bits. Leur nombre, à l'exception des registres de segments, est le même que celui du i8086, mais la dimension est plus grande, ce qui se reflète dans leurs désignations - ils ont
préfixe e (étendu).

^ Registres à usage général
Tous les registres de ce groupe permettent d'accéder à leurs parties « inférieures » (voir Fig. 3). En regardant cette figure, notez que 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. Ceci est fait, comme nous l'avons noté ci-dessus, pour la compatibilité avec les modèles de microprocesseurs 16 bits plus récents d'Intel.

Listons les registres appartenant au groupe des registres à usage général. Étant donné que ces registres sont physiquement situés dans le microprocesseur à l'intérieur de l'unité arithmétique et logique (ALU), ils sont également appelés registres ALU :

eax/ax/ah/al (registre d'accumulateur) - accumulateur.
Utilisé pour stocker des données intermédiaires. Dans certaines commandes, l'utilisation de ce registre est obligatoire ;

ebx/bx/bh/bl (registre de base) - registre de base.
Utilisé pour stocker l'adresse de base d'un objet en mémoire ;

ecx/cx/ch/cl (registre de comptage) - registre de compteur.
Il est utilisé dans les commandes qui effectuent des actions répétitives. Son utilisation est souvent implicite et cachée dans l'algorithme de la commande correspondante.
Par exemple, la commande d'organisation de boucle, en plus de transférer le contrôle à une commande située à une certaine adresse, analyse et décrémente de un la valeur du registre ecx/cx ;

edx/dx/dh/dl (registre de données) - registre de données.
Tout comme le registre eax/ax/ah/al, il stocke des données intermédiaires. Certaines commandes nécessitent son utilisation ; pour certaines commandes, cela se produit implicitement.

Les deux registres suivants sont utilisés pour prendre en charge les opérations dites en chaîne, c'est-à-dire les opérations qui traitent séquentiellement des chaînes d'éléments, chacune pouvant avoir une longueur de 32, 16 ou 8 bits :

esi/si (registre d'index source) - index source.
Ce registre dans les opérations en chaîne contient l'adresse courante de l'élément dans la chaîne source ;

edi/di (registre d'index de destination) - index du récepteur (destinataire).
Ce registre dans les opérations en chaîne contient l'adresse courante dans la chaîne de destination.

Dans l'architecture du microprocesseur au niveau matériel et logiciel, une structure de données telle qu'une pile est supportée. Pour travailler avec la pile dans le système d'instructions du microprocesseur, il existe des commandes spéciales, et dans le modèle logiciel du microprocesseur, il existe des registres spéciaux pour cela:

esp/sp (registre de pointeur de pile) - registre de pointeur de pile.
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 cadre de pile.
Conçu pour organiser un accès aléatoire aux données à l'intérieur de la pile.

Une pile est une zone de programme pour le stockage temporaire de données arbitraires. Bien entendu, des données peuvent également être stockées dans le segment de données, mais dans ce cas, pour chaque donnée temporairement stockée, une cellule mémoire nommée distincte doit être créée, ce qui augmente la taille du programme et le nombre de noms utilisés. La commodité de la pile est que sa zone est réutilisée, et le stockage des données sur la pile et leur extraction à partir de là se font à l'aide de commandes push et pop efficaces sans spécifier de noms.
La pile est traditionnellement utilisée, par exemple, pour stocker le contenu des registres utilisés par le programme avant d'appeler un sous-programme, qui, à son tour, utilisera les registres du processeur "pour ses propres besoins". Le contenu d'origine des registres s'échappe de la pile lors du retour du sous-programme. Une autre technique courante consiste à transmettre les paramètres requis à un sous-programme via la pile. Le sous-programme, sachant dans quel ordre les paramètres sont placés sur la pile, peut les prendre à partir de là et les utiliser dans son exécution. Particularité pile est une sorte d'ordre d'échantillonnage des données qu'elle contient : à tout moment, seul l'élément supérieur est disponible sur la pile, c'est-à-dire le dernier élément chargé sur la pile. Faire sauter l'élément supérieur de la pile rend l'élément suivant disponible. Les éléments de la pile sont situés dans la zone de mémoire allouée à la pile, en partant du bas de la pile (c'est-à-dire depuis son adresse maximale) jusqu'aux adresses successivement décroissantes. L'adresse de l'élément accessible par le haut est stockée dans le registre de pointeur de pile SP. Comme toute autre zone de la mémoire programme, la pile doit être incluse dans un segment ou former un segment séparé. Dans les deux cas, l'adresse de segment de ce segment est placée dans le registre de pile de segments SS. Ainsi, une paire de registres SS:SP décrit l'adresse d'une cellule de pile disponible : SS stocke l'adresse de segment de la pile, et SP stocke le décalage des dernières données stockées sur la pile (Fig. 4, a). Faisons attention au fait que dans l'état initial, le pointeur de pile SP pointe vers une cellule qui se trouve sous le bas de la pile et n'y est pas incluse.

Fig 4. Organisation de la pile : a - l'état initial, b - après chargement d'un élément (c cet exemple- le contenu du registre AX), c - après le chargement du deuxième élément (le contenu du registre DS), d - après le déchargement d'un élément, e - après le déchargement de deux éléments et le retour à son état d'origine.

Le chargement sur la pile est effectué par une commande spéciale push stack. Cette instruction décrémente d'abord le contenu du pointeur de pile de 2, puis place l'opérande à l'adresse dans SP. Si, par exemple, nous voulons enregistrer temporairement le contenu du registre AX sur la pile, nous devons exécuter la commande

La pile passe à l'état illustré à la Fig. 1.10, b. On peut voir que le pointeur de pile est décalé de deux octets (vers les adresses inférieures) et l'opérande spécifié dans la commande push est écrit à cette adresse. La commande suivante pour charger sur la pile, par exemple,

déplacera la pile dans l'état illustré à la Fig. 1.10, ch. La pile contiendra désormais deux éléments, seul celui du haut étant accessible, pointé par le pointeur de pile SP. Si après un certain temps nous avons besoin de restaurer le contenu d'origine des registres enregistrés sur la pile, nous devons exécuter les commandes pour décharger de la pile pop (pop):

pop-DS
HACHE pop

Quelle doit être la taille de la pile ? Cela dépend de l'intensité de son utilisation dans le programme. Si, par exemple, vous envisagez de stocker un tableau de 10 000 octets sur la pile, la pile doit avoir au moins cette taille. Il convient de garder à l'esprit que dans certains cas, la pile est automatiquement utilisée par le système, en particulier lors de l'exécution de la commande d'interruption int 21h. Avec cette commande, le processeur pousse d'abord l'adresse de retour sur la pile, puis DOS y pousse le contenu des registres et d'autres informations relatives au programme interrompu. Par conséquent, même si le programme n'utilise pas du tout la pile, celle-ci doit toujours être présente dans le programme et avoir une taille d'au moins plusieurs dizaines de mots. Dans notre premier exemple, nous mettons 128 mots sur la pile, ce qui est largement suffisant.

^ Structure du programme d'assemblage

Un programme en langage assembleur est un ensemble de blocs de mémoire appelés segments de mémoire. Un programme peut consister en un ou plusieurs de ces blocs-segments. Chaque segment contient une collection de phrases de langage, dont chacune occupe une ligne distincte de code de programme.

Les instructions d'assemblage sont de quatre types :

commandes ou instructions qui sont les équivalents symboliques des instructions machine. Pendant le processus de traduction, les instructions d'assemblage sont converties en commandes correspondantes du jeu d'instructions du microprocesseur ;

macro-commandes - phrases du texte du programme conçues d'une certaine manière et remplacées par d'autres phrases lors de la traduction;

directives qui indiquent au compilateur assembleur d'effectuer une action. Les directives n'ont pas d'équivalent dans la représentation machine ;

lignes de commentaire contenant n'importe quel caractère, y compris les lettres de l'alphabet russe. Les commentaires sont ignorés par le traducteur.

^ Syntaxe du langage d'assemblage

Les phrases qui composent un programme peuvent être une construction syntaxique correspondant à une commande, une macro, une directive ou un commentaire. Pour que le traducteur assembleur les reconnaisse, ils doivent être formés selon certaines règles syntaxiques. Pour ce faire, il est préférable d'utiliser une description formelle de la syntaxe du langage, comme les règles de grammaire. Les façons les plus courantes de décrire un langage de programmation de cette manière sont les diagrammes de syntaxe et les formes Backus-Naur étendues. Pour une utilisation pratique, les diagrammes de syntaxe sont plus pratiques. Par exemple, la syntaxe des instructions en langage assembleur peut être décrite à l'aide des diagrammes de syntaxe illustrés dans les figures suivantes.

Riz. 5. Format de phrase en assembleur

Riz. 6. Directives de format

Riz. 7. Format des commandes et des macros

Sur ces dessins :

nom d'étiquette - un identifiant dont la valeur est l'adresse du premier octet de la phrase du code source du programme, qu'il désigne;

name - un identifiant qui distingue cette directive des autres directives du même nom. Suite au traitement par l'assembleur d'une certaine directive, certaines caractéristiques peuvent être affectées à ce nom ;

le code d'opération (COP) et la directive sont des désignations mnémoniques de l'instruction machine, de la macro-instruction ou de la directive de traduction correspondantes ;

opérandes - parties de la commande, de la macro ou des directives de l'assembleur, désignant les objets sur lesquels les opérations sont effectuées. Les opérandes assembleur sont décrits par des expressions avec des constantes numériques et textuelles, des étiquettes de variables et des identificateurs utilisant des signes d'opérateur et des mots réservés.

^ Comment utiliser les diagrammes de syntaxe ? C'est très simple : il suffit de trouver puis de suivre le chemin de l'entrée du diagramme (à gauche) à sa sortie (à droite). Si un tel chemin existe, alors la phrase ou la construction est syntaxiquement correcte. Si un tel chemin n'existe pas, le compilateur n'acceptera pas cette construction. Lorsque vous travaillez avec des diagrammes de syntaxe, faites attention au sens de parcours indiqué par les flèches, car parmi les chemins, il peut y avoir ceux qui peuvent être suivis de droite à gauche. En fait, les diagrammes syntaxiques reflètent la logique du traducteur lors de l'analyse des phrases d'entrée du programme.

Les caractères autorisés lors de l'écriture du texte des programmes sont :

Toutes les lettres latines : A-Z, a-z. Dans ce cas, les majuscules et les minuscules sont considérées comme équivalentes ;

Chiffres de 0 à 9 ;

Signes ?, @, $, _, & ;

Séparateurs, . ()< > { } + / * % ! " " ? \ = # ^.

Les phrases en assembleur sont formées à partir de lexèmes, qui sont des séquences syntaxiquement inséparables de symboles linguistiques valides qui ont un sens pour le traducteur.

Les jetons sont :

les identificateurs sont des séquences de caractères valides utilisés pour désigner des objets de programme tels que des opcodes, des noms de variables et des noms d'étiquettes. La règle d'écriture des identifiants est la suivante : un identifiant peut être composé d'un ou plusieurs caractères. En tant que caractères, vous pouvez utiliser des lettres de l'alphabet latin, des chiffres et certains caractères spéciaux - _, ?, $, @. Un identifiant ne peut pas commencer par un chiffre. La longueur de l'identifiant peut aller jusqu'à 255 caractères, bien que le traducteur n'accepte que les 32 premiers caractères et ignore le reste. Vous pouvez ajuster la longueur des identifiants possibles à l'aide de l'option ligne de commande mv. De plus, il est possible de dire au traducteur de faire la distinction entre les lettres majuscules et minuscules ou d'ignorer leur différence (ce qui est fait par défaut).

^ Commandes du langage d'assemblage.

Les commandes d'assemblage révèlent la capacité de transférer leurs exigences à l'ordinateur, le mécanisme de transfert de contrôle dans le programme (boucles et sauts) pour les comparaisons logiques et l'organisation du programme. Cependant, les tâches de programmation sont rarement aussi simples. La plupart des programmes contiennent une série de boucles dans lesquelles plusieurs instructions sont répétées jusqu'à ce qu'une certaine exigence soit atteinte, et diverses vérifications pour déterminer laquelle des plusieurs actions à effectuer. Certaines commandes peuvent transférer le contrôle en modifiant la séquence normale d'étapes en modifiant directement la valeur de décalage dans le pointeur de commande. Comme mentionné précédemment, il existe différentes commandes pour différents processeurs, mais nous considérerons un certain nombre de commandes pour les processeurs 80186, 80286 et 80386.

Pour décrire l'état des drapeaux après l'exécution d'une certaine commande, nous utiliserons une sélection du tableau qui reflète la structure du registre des drapeaux eflags :

La ligne du bas de ce tableau répertorie les valeurs des drapeaux après l'exécution de la commande. Dans ce cas, les notations suivantes sont utilisées :

1 - après l'exécution de la commande, le drapeau est défini (égal à 1) ;

0 - après l'exécution de la commande, le drapeau est réinitialisé (égal à 0) ;

r - la valeur du drapeau dépend du résultat de la commande ;

Après l'exécution de la commande, le drapeau est indéfini ;

espace - après l'exécution de la commande, le drapeau ne change pas ;

La notation suivante est utilisée pour représenter les opérandes dans les diagrammes de syntaxe :

r8, r16, r32 - opérande dans l'un des registres de taille octet, mot ou double mot ;

m8, m16, m32, m48 - taille de l'opérande en mémoire d'octets, mot, double mot ou 48 bits ;

i8, i16, i32 - opérande immédiat de taille octet, mot ou double mot ;

a8, a16, a32 - adresse relative (décalage) dans le segment de code.

Commandes (par ordre alphabétique) :

*Ces commandes sont décrites en détail.

AJOUTER
(Ajout)

Ajout

^ Aperçu de la commande :

ajouter destination, source

Objet : ajout de deux opérandes source et destination de dimensions octet, mot ou double mot.

Algorithme de travail :

ajouter les opérandes source et destination ;

écrire le résultat de l'addition au récepteur ;

définir des drapeaux.

Etat des flags après exécution de la commande :

Application:
La commande add est utilisée pour additionner deux opérandes entiers. Le résultat de l'addition est placé à l'adresse du premier opérande. Si le résultat de l'addition dépasse les bornes de l'opérande destination (un débordement se produit), alors cette situation doit être prise en compte en analysant le flag cf puis éventuellement en utilisant la commande adc. Par exemple, ajoutons les valeurs dans le registre ax et la zone mémoire ch. Lors de l'ajout, vous devez tenir compte de la possibilité de débordement.

Registre plus registre ou mémoire :

|000000dw|modregr/rm|

Registre AX (AL) plus valeur immédiate :

|0000010w|--données--|données si w=1|

Registre ou mémoire plus valeur immédiate :

|100000sw|mod000r/m|--données--|données si BW=01|

APPEL
(APPEL)

Appel d'une procédure ou d'une tâche

^ Aperçu de la commande :

Objectif:

transfert de contrôle à une procédure close ou far avec mémorisation de l'adresse du point de retour sur la pile ;

le changement de tâche.

Algorithme de travail :
déterminé par le type d'opérande :

L'étiquette est proche - le contenu du pointeur de commande eip / ip est poussé sur la pile et une nouvelle valeur d'adresse correspondant à l'étiquette est chargée dans le même registre ;

Far label - le contenu des pointeurs de commande eip/ip et cs est poussé sur la pile. Ensuite, les nouvelles valeurs d'adresse correspondant à la marque lointaine sont chargées dans les mêmes registres ;

R16, 32 ou m16, 32 - définissent un registre ou une cellule de mémoire contenant des décalages dans le segment d'instruction en cours, où le contrôle est transféré. Lorsque le contrôle est transféré, le contenu du pointeur de commande eip/ip est poussé sur la pile ;

Pointeur mémoire - définit un emplacement mémoire contenant un pointeur de 4 ou 6 octets vers la procédure appelée. La structure d'un tel pointeur est de 2+2 ou 2+4 octets. L'interprétation d'un tel pointeur dépend du mode de fonctionnement du microprocesseur :

^ État des drapeaux après l'exécution de la commande (sauf changement de tâche) :

l'exécution de la commande n'affecte pas les drapeaux

Lorsqu'une tâche est commutée, les valeurs des drapeaux sont modifiées en fonction des informations sur le registre eflags dans le segment d'état TSS de la tâche vers laquelle basculer.
Application:
La commande d'appel permet d'organiser un transfert de contrôle flexible et multivarié vers un sous-programme tout en conservant l'adresse du point de retour.

Code objet (quatre formats) :

Adressage direct dans un segment :

|11101000|disp-bas|diep-haut|

Adressage indirect dans un segment :

|11111111|mod010r/m|

Adressage indirect entre segments :

|11111111|mod011r/m|

Adressage direct entre segments :

|10011010|décalage-bas|décalage-haut|seg-bas|seg-haut|

CMP
(comparer les opérandes)

Comparaison d'opérandes

^ Aperçu de la commande :

cmp opérande1, opérande2

Objet : comparaison de deux opérandes.

Algorithme de travail :

effectuer une soustraction (opérande1-opérande2);

en fonction du résultat, définissez des drapeaux, ne modifiez pas l'opérande1 et l'opérande2 (c'est-à-dire, ne stockez pas le résultat).

Application:
Cette commande utilisé pour comparer deux opérandes par soustraction, alors que les opérandes ne changent pas. Les drapeaux sont définis à la suite de l'exécution de la commande. L'instruction cmp est utilisée avec les instructions de saut conditionnel et l'instruction set octet par valeur setcc.

Code objet (trois formats) :

Registre ou mémoire enregistrée :

|001110dw|modreg/m|

Valeur immédiate avec registre AX (AL) :

|0011110w|--données--|données si w=1|

Valeur immédiate avec registre ou mémoire :

|100000sw|mod111r/m|--données--|données si sw=0|

DÉC
(Décrémenter l'opérande de 1)

Opérande décrémenté de un

^ Aperçu de la commande :

déc opérande

But : diminuer la valeur de l'opérande en mémoire ou registre de 1.

Algorithme de travail :
l'instruction soustrait 1 à l'opérande. Etat des flags après exécution de la commande :

Application:
La commande dec est utilisée pour décrémenter la valeur d'un octet, d'un mot, d'un double mot en mémoire ou d'un registre de un. Notez que la commande n'affecte pas l'indicateur cf.

Registre : |01001reg|

^ Registre ou mémoire : |1111111w|mod001r/m|

DIV
(DIVide non signé)

Section non signée

Schéma de commande :

diviseur div

Objectif : effectuer une opération de division sur deux valeurs binaires non signées.

^ Algorithme de travail :
La commande nécessite deux opérandes - le dividende et le diviseur. Le dividende est spécifié implicitement et sa taille dépend de la taille du diviseur, qui est spécifiée dans la commande :

si le diviseur est en octets, alors le dividende doit être situé dans le registre ax. Après l'opération, le quotient est mis en al et le reste en ah ;

si le diviseur est un mot, alors le dividende doit se situer dans le couple de registres dx:ax, avec la partie basse du dividende dans ax. Après l'opération, le quotient est mis en ax et le reste en dx ;

si le diviseur est un mot double, alors le dividende doit se situer dans le couple de registres edx:eax, avec la partie basse du dividende dans eax. Après l'opération, le quotient est placé dans eax et le reste dans edx.

^ État des drapeaux après exécution de la commande :

Application:
La commande effectue une division entière des opérandes, renvoyant le résultat de la division sous forme de quotient et le reste de la division. Lors de l'exécution d'une opération de division, une exception peut se produire : 0 - erreur de division. Cette situation se produit dans l'un des deux cas suivants : le diviseur est 0 ou le quotient est trop grand pour tenir dans le registre eax/ax/al.

Code objet:

|1111011w|mod110r/m|

INT
(Couper la parole)

Appel d'une routine de service d'interruption

^ Aperçu de la commande :

int interruption_numéro

Objet : appeler la routine de service d'interruption avec le numéro d'interruption spécifié par l'opérande d'instruction.

^ Algorithme de travail :

poussez le registre eflags/flags et l'adresse de retour sur la pile. Lors de l'écriture de l'adresse de retour, le contenu du registre de segment cs est d'abord écrit, puis le contenu du pointeur de commande eip/ip ;

remettre à zéro les drapeaux if et tf ;

transférer le contrôle au gestionnaire d'interruption avec le numéro spécifié. Le mécanisme de transfert de commande dépend du mode de fonctionnement du microprocesseur.

^ État des drapeaux après exécution de la commande :

Application:
Comme vous pouvez le voir dans la syntaxe, il existe deux formes de cette commande :

int 3 - a son propre opcode individuel 0cch et occupe un octet. Cette circonstance le rend très pratique à utiliser dans divers débogueurs de logiciels pour définir des points d'arrêt en remplaçant le premier octet de toute instruction. Le microprocesseur, rencontrant une commande avec l'opcode 0cch dans la séquence de commandes, appelle le gestionnaire d'interruption avec le vecteur numéro 3, qui sert à communiquer avec le débogueur logiciel.

La deuxième forme de l'instruction a une longueur de deux octets, a un opcode de 0cdh et vous permet d'initier un appel à une routine de service d'interruption avec un numéro de vecteur dans la plage 0-255. Les caractéristiques du transfert de contrôle, comme indiqué, dépendent du mode de fonctionnement du microprocesseur.

Code objet (deux formats) :

S'inscrire : |01000reg|

^ Registre ou mémoire : |1111111w|mod000r/m|

CCJ
JCXZ/JECXZ
(Sauter si condition)

(Sauter si CX=Zero/ Sauter si ECX=Zero)

Sauter si la condition est remplie

Sauter si CX/ECX est nul

^ Aperçu de la commande :

label jcc
étiquette jcxz
étiquette jecxz

Objectif : transition dans le segment actuel des commandes, en fonction de certaines conditions.

^ Algorithme de commande (sauf pour jcxz/jecxz) :
Vérification de l'état des drapeaux en fonction de l'opcode (il reflète la condition vérifiée) :

si la condition testée est vraie, aller à la cellule indiquée par l'opérande ;

si la condition vérifiée est fausse, passez le contrôle à la commande suivante.

Algorithme de commande jcxz/jecxz :
Vérification de la condition que le contenu du registre ecx/cx soit égal à zéro :

si la condition cochée

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

Étiquette 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
.LES DONNÉES
.CODE
DÉBUT:

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.

Commandes en langage assembleur (Cours)

PLAN DE CONFÉRENCE

1. Principaux groupes d'opérations.

Pentium.

1. Principaux groupes d'opérations

Les microprocesseurs exécutent un ensemble d'instructions qui implémentent les principaux groupes d'opérations suivants :

opérations de transit,

opérations arithmétiques,

opérations logiques,

opérations de quart de travail,

opérations de comparaison et de test,

opérations sur les bits,

opérations de gestion du programme ;

Opérations de contrôle du processeur.

2. Mnémocodes des commandes du processeur Pentium

Lors de la description des commandes, leurs désignations mnémoniques (codes mnémoniques) sont généralement utilisées, qui servent à spécifier la commande lors de la programmation en langage assembleur. Pour différentes versions Les mnémoniques de l'assembleur pour certaines commandes peuvent différer. Par exemple, pour une commande d'appel d'un sous-programme, le code mnémonique est utiliséAPPEL ou RSC ("Sauter à sous-programme”). Cependant, les codes mnémoniques de la plupart des commandes des principaux types de microprocesseurs sont identiques ou diffèrent légèrement, car ce sont des abréviations des mots anglais correspondants qui définissent l'opération en cours. Considérez les mnémoniques de commande adoptés pour les processeurs Pentium.

Transférer les commandes. La commande principale de ce groupe est la commandeMOV , qui assure le transfert de données entre deux registres ou entre un registre et une cellule mémoire. Certains microprocesseurs mettent en oeuvre un transfert entre deux cellules mémoire, ainsi qu'un transfert groupé du contenu de plusieurs registres depuis la mémoire. Par exemple, les microprocesseurs de la famille 68 Motorola xxx exécuter la commandeMOUVEMENT , qui assure le transfert d'une cellule mémoire à une autre, et la commandeMOVEM , qui écrit en mémoire ou charge depuis la mémoire le contenu d'un ensemble donné de registres (jusqu'à 16 registres). ÉquipeXCHG effectue un échange mutuel du contenu de deux registres du processeur ou d'un registre et d'une cellule mémoire.

Commandes d'entrée DANS et sortie DEHORS mettre en œuvre le transfert de données du registre du processeur vers un dispositif externe ou la réception de données d'un dispositif externe vers le registre. Ces commandes spécifient le numéro du périphérique d'interface (port d'E/S) par lequel les données sont transférées. Notez que de nombreux microprocesseurs n'ont pas d'instructions spéciales pour accéder périphériques externes. Dans ce cas, l'entrée et la sortie des données dans le système sont effectuées à l'aide de la commandeMOV , qui spécifie l'adresse du périphérique d'interface requis. Ainsi, un périphérique externe est adressé en tant que cellule de mémoire et une section spécifique est allouée dans l'espace d'adressage, dans laquelle se trouvent les adresses des périphériques d'interface (ports) connectés au système.

Commandes pour les opérations arithmétiques. Les principales commandes de ce groupe sont l'addition, la soustraction, la multiplication et la division, qui ont un certain nombre d'options. Commandes supplémentaires AJOUTER et soustraction SOUS effectuer les opérations appropriées aveccpossédant deux registres, un registre et un emplacement mémoire, ou utilisant un opérande immédiat. Équipes UN D C , SB B effectuer des additions et des soustractions en tenant compte de la valeur de l'attributC, défini lors de la formation du transfert dans le processus d'exécution de l'opération précédente. A l'aide de ces commandes, l'addition séquentielle d'opérandes est mise en œuvre, dont le nombre de chiffres dépasse la capacité du processeur. Équipe NEG change le signe de l'opérande, le convertissant en complément à deux.

Les opérations de multiplication et de division peuvent être effectuées sur des nombres signés (commandesje MUL, je DIV ) ou non signé (commandes MUL, DIV ). Le résultat de l'opération se trouve dans le registre. Lors de la multiplication (commandesMUL , IMUL ) donne un résultat à deux chiffres, qui utilise deux registres pour s'adapter. Lors de la division (commandesDIV , IDIV ) comme dividende, on utilise un opérande de capacité doublée, placé dans deux registres, et par conséquent, le quotient et le reste sont écrits dans deux registres.

Commandes logiques . Presque tous les microprocesseurs effectuent des opérations logiques ET, OU, OU exclusif, qui sont effectuées sur les bits d'opérande du même nom à l'aide de commandes ET, OU, X OU . Les opérations sont effectuées sur le contenu de deux registres, un registre et un emplacement mémoire, ou à l'aide d'un opérande immédiat. Équipe NE PAS Inverse la valeur de chaque bit de l'opérande.

Commandes de décalage. Des microprocesseurs effectuent des décalages arithmétiques, logiques et cycliques des opérandes adressés d'un ou plusieurs bits. L'opérande à décaler peut se trouver dans un registre ou un emplacement mémoire, et le nombre de bits de décalage est spécifié à l'aide de l'opérande immédiat contenu dans l'instruction, ou déterminé par le contenu du registre spécifié. Le signe de transfert est généralement impliqué dans la mise en œuvre du changementCdans le registre d'état (RS ou EFLAGS), qui contient le dernier bit de l'opérande extrait du registre ou de l'emplacement mémoire.

Commandes de comparaison et de test . La comparaison d'opérandes se fait généralement avec l'instructionCMP , qui effectue la soustraction des opérandes en définissant les valeurs des caractéristiques N, Z, V, C dans le registre d'état en fonction du résultat. Dans ce cas, le résultat de la soustraction n'est pas enregistré et les valeurs des opérandes ne changent pas. L'analyse ultérieure des valeurs caractéristiques obtenues permet de déterminer la valeur relative (>,<, =) операндов со знаком или без знака. Использование различных способов адресации позволяет производит сравнение содержимого двух регистров, регистра и ячейки памяти, непосредственно заданного операнда с содержимым регистра или ячейки памяти.

Certains microprocesseurs exécutent une commande de test TCT , qui est une variante à opérande unique de l'instruction de comparaison. Lorsque cette commande est exécutée, les signes sont définis N, Z selon le signe et la valeur (égale ou non nulle) de l'opérande adressé.

Instructions d'utilisation des bits . Ces commandes définissent la valeur de l'attributCdans le registre d'état en fonction de la valeur du bit testémilliards dans l'opérande adressé. Dans certains microprocesseurs, selon le résultat du test un peu, un signe est définiZ. Numéro de bit de testnest défini soit par le contenu du registre spécifié dans la commande, soit par un opérande immédiat.

Les commandes de ce groupe implémentent différentes options pour changer le bit testé. BT conserve la valeur de ce bit inchangée.Command B J S après le test définit la valeur milliards=1, et la commande B J C - sens milliards=0.Commande B J C inverse la valeur du bit bn après l'avoir testé.

Opérations de gestion du programme. Pour contrôler le programme, un grand nombre de commandes sont utilisées, parmi lesquelles:

- commandes de transfert de contrôle inconditionnel ;

- commandes de saut conditionnel ;

- commandes d'organisation des cycles de programme ;

- commandes d'interruption ;

- commandes de changement de fonctionnalité.

Le transfert de contrôle inconditionnel est effectué par la commandeJMP , qui se charge dans le compteur de programmePCnouveau contenu qui est l'adresse de la prochaine commande à exécuter. Cette adresse est soit directement spécifiée dans la commandeJMP (adresse directe), ou calculé comme la somme du contenu actuelPCet le décalage spécifié dans la commande, qui est un nombre signé (adressage relatif). CarPCcontient l'adresse de la prochaine commande du programme, alors la dernière méthode fixe l'adresse de la transition, décalée par rapport à l'adresse suivante d'un nombre d'octets donné. Si le décalage est positif, le passage aux commandes suivantes du programme est effectué, si le décalage est négatif, aux précédentes.

Le sous-programme est également appelé par transfert de contrôle inconditionnel à l'aide de la commandeAPPEL (ou RSC ). Cependant, dans ce cas, avant de charger dansPC nouveau contenu qui spécifie l'adresse de la première instruction du sous-programme, il est nécessaire de sauvegarder sa valeur courante (l'adresse de l'instruction suivante) afin d'assurer un retour au programme principal après l'exécution du sous-programme (ou au sous-programme précédent lors de l'imbrication de sous-programmes). Les instructions de saut conditionnel (branches de programme) sont chargées dansPCnouveau contenu si certaines conditions sont remplies, qui sont généralement définies en fonction de la valeur actuelle de divers attributs dans le registre d'état. Si la condition n'est pas remplie, la commande de programme suivante est exécutée.

Les commandes de gestion des traits permettent d'écrire - de lire le contenu du registre d'état, qui stocke les traits, ainsi que de modifier les valeurs des traits individuels. Par exemple, les processeurs Pentium implémentent des commandes LAHF et SAHF , qui chargent l'octet de poids faible, qui contient les signes, à partir du registre d'état EFLAGà l'octet de poids faible du registre EAX et rembourrage octet de poids faible EFLAGS du registre EAX.. Commandes CLC, STC définir les valeurs du drapeau de transfert CF=0, CF=1, et la commande CMC provoque l'inversion de la valeur de cette caractéristique.Étant donné que les traits déterminent le flux d'exécution du programme pendant les sauts conditionnels, les instructions de changement de trait sont généralement utilisées pour contrôler le programme.

Commandes de contrôle du processeur . Ce groupe comprend les commandes d'arrêt, aucune opération et un certain nombre de commandes qui déterminent le mode de fonctionnement du processeur ou de ses blocs individuels. ÉquipeHLT termine l'exécution du programme et place le processeur dans un état d'arrêt, dont la sortie se produit à la réception de signaux d'interruption ou de redémarrage ( réinitialiser). Équipe NON Une instruction ("vide"), qui n'entraîne aucune opération, est utilisée pour implémenter des retards de programme ou combler des lacunes formées dans le programme.

Équipes spéciales CLI, IST désactiver et activer le service des demandes d'interruption. Dans les processeurs Pentium un bit de contrôle (drapeau) est utilisé pour celaSI dans le registre EFLAGS.

De nombreux microprocesseurs modernes émettent une commande d'identification qui permet à l'utilisateur ou à d'autres appareils d'obtenir des informations sur le type de processeur utilisé dans un système donné. Dans les processeurs Pentuim c'est à ça que sert la commande ID CPU , au cours de laquelle les données nécessaires sur le processeur entrent dans les registres EAX,ebx,ECX,EDX et peut ensuite être lu par l'utilisateur ou le système d'exploitation.

Selon les modes de fonctionnement mis en œuvre par le processeur et les types de données traitées spécifiés, l'ensemble des commandes exécutables peut être considérablement élargi.

Certains processeurs effectuent des opérations arithmétiques BCD ou exécutent des instructions spéciales de correction de résultat lors du traitement de ces nombres. De nombreux processeurs hautes performances incluent UPC - bloc de traitement des nombres c "point flottant".

Dans un certain nombre de processeurs modernes, un traitement de groupe de plusieurs nombres entiers ou nombres est mis en œuvre. c "virgule flottante" avec une seule commande selon le principe SIMD ("Instruction unique - Données multiples ”) - “Une commande – Beaucoup de données”. L'exécution simultanée d'opérations sur plusieurs opérandes augmente considérablement les performances du processeur lors de l'utilisation de données vidéo et audio. De telles opérations sont largement utilisées dans le traitement d'image, le traitement du signal audio et d'autres applications. Pour effectuer ces opérations, des blocs spéciaux sont introduits dans les processeurs qui implémentent les ensembles d'instructions correspondants, qui dans différents types de processeurs ( Pentium, Athènes) a obtenu le nomMMX (“ Milti-Extension média ”) – Extension Multimédia,ESS(« Extension SIMD en continu ») – SIMD en continu - extension, “3 Extension- Extension 3D.

Une caractéristique des processeurs de l'entreprise Intel , à partir du modèle 80286, est le contrôle de priorité lors de l'accès à la mémoire, qui est fourni lorsque le processeur fonctionne en mode d'adresse virtuelle protégée - " Mode protégé " (mode protégé). Pour mettre en œuvre ce mode, des groupes spéciaux de commandes sont utilisés, qui servent à organiser la protection de la mémoire conformément à l'algorithme d'accès prioritaire accepté.

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'un

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. L'unité centrale comprend la carte système, le bloc d'alimentation et les connecteurs d'extension pour cartes supplémentaires. La carte mère contient le microprocesseur, la mémoire morte (ROM), la mémoire vive (RAM) et le 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) - la 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 - compteur(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 la 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) - S'inscrire 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. Les registres de segment sont utilisés pour indiquer quels segments sont actuellement disponibles. 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 commandes. 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) - S'inscrire 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 sans signe, 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 pancarte. 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 de la mémoire virtuelle, 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é. En mode protégé, il devient possible d'effectuer le traitement multitâche de l'information, 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-à-dire 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 double mot, 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 à son tour est représenté dans le forme "inversée". 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.

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 est 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% des 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 logiciel d'un 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.

MAIS– 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 interne MP. 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, il y a un 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 (l'option la plus pratique et la plus 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. Il existe diverses méthodes par lesquelles le code d'instruction peut déterminer d'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;

S'inscrire;

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 l'instruction, 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.

S'inscrire 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 aux cellules 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
LES 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)
Partager