Le langage d'assemblage de la commande. Résumé: Plan: Préface

L'UNIVERSITÉ NATIONALE D'OUZBÉKISTAN NOMMÉE APRÈS MIRZO ULUGBEK

FACULTÉ DE TECHNOLOGIE INFORMATIQUE

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

Terminé:

Tachkent 2003.

Avant-propos.

Langage d'assemblage et structure de commande.

Structure de fichier EXE (analyse sémantique).

Structure du fichier COM.

Le principe de fonctionnement et de propagation du virus.

Démonteur.

Programmes.

Préface

La profession de programmeur est incroyable et unique. À notre époque, la science et la vie ne peuvent être imaginées sans les dernières technologies. Tout ce qui touche à l'activité humaine n'est pas complet sans la technologie informatique. Et cela contribue à son développement et à sa perfection. Bien que le développement des ordinateurs personnels ait commencé il n'y a pas si longtemps, pendant cette période, des mesures colossales ont été prises dans les produits logiciels et ces produits seront largement utilisés pendant longtemps. Le domaine des connaissances informatiques a explosé, tout comme la technologie connexe. Si vous ne prenez pas en considération l'aspect commercial, nous pouvons dire qu'il n'y a pas d'étrangers dans ce domaine d'activité professionnelle. Beaucoup sont engagés dans le développement de programmes à but non lucratif ou lucratif, mais de leur plein gré, par passe-temps. Bien sûr, cela ne devrait pas affecter la qualité du programme, et dans ce métier, pour ainsi dire, «business», il y a concurrence et demande pour des performances de qualité, un travail stable et répondant à toutes les exigences de notre temps. Il convient également de noter ici l'émergence des microprocesseurs dans les années 60, qui sont venus remplacer un grand nombre de jeux de lampes. Il existe certains types de microprocesseurs qui sont très différents les uns des autres. Ces microprocesseurs diffèrent les uns des autres par la taille des bits et les 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 prolifération des micro-ordinateurs a conduit à une redéfinition du langage d'assemblage pour deux raisons principales. Premièrement, les programmes écrits en langage assembleur nécessitent beaucoup moins de mémoire et d'exécution. Deuxièmement, la connaissance du langage d'assemblage et du code machine résultant permet de comprendre l'architecture de la machine, ce qui n'est guère possible lorsque l'on travaille dans un langage de haut niveau. Alors que la plupart des professionnels du logiciel développent dans des langages de haut niveau tels que Pascal, C ou Delphi, qui sont plus faciles à écrire, le logiciel le plus puissant et le plus efficace est écrit en tout ou en partie en langage assembleur. Les langages de haut niveau ont été conçus pour éviter la technicité particulière d'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 d'assemblage pour un ordinateur particulier, il faut connaître son architecture. Aujourd'hui, le principal produit logiciel est le fichier EXE. Compte tenu des aspects positifs de cela, l'auteur du programme peut être sûr de son intégrité. Mais ce n'est souvent pas le cas. Il y a aussi un démonteur. À 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 connaît bien le langage d'assemblage de refaire l'ensemble du programme à son goût. Peut-être de là vient le problème le plus insoluble - le virus. Pourquoi les gens écrivent-ils un virus? Certaines personnes posent cette question avec surprise, d'autres avec colère, mais néanmoins, il y a encore des gens qui s'intéressent à ce problème non pas du point de vue de causer du tort, mais comme un intérêt pour la programmation système. Les virus écrivent pour diverses raisons. Certaines personnes aiment les appels système, d'autres aiment améliorer leurs connaissances en assembleur. J'essaierai de décrire tout cela dans mon mémoire. Il parle également non seulement de la structure du fichier EXE, mais également du langage d'assemblage.

^ Langue d'assemblage.

Il est intéressant de retracer, de l'époque des premiers ordinateurs à nos jours, les transformations de la compréhension du langage d'assemblage chez les programmeurs.

Il était une fois l'assembleur était un langage sans connaissance dont il était impossible de faire faire quelque chose d'utile à un ordinateur. La situation a progressivement changé. Des moyens plus pratiques de communiquer 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? À la recherche d'une réponse, essayons de comprendre ce qu'est le langage d'assemblage en général.

En bref, le langage assembleur est une représentation symbolique d'un langage machine. Tous les processus de la machine, au niveau matériel le plus bas, sont uniquement pilotés par des commandes en langage machine (instructions). Il est donc clair que, malgré le nom général, le langage d'assemblage pour chaque type d'ordinateur est différent. Cela s'applique également à l'apparence des programmes écrits en langage assembleur et aux idées dont ce langage est le reflet.

Il est impossible de vraiment résoudre les problèmes liés au matériel (ou même les problèmes liés au matériel tels que l'amélioration des performances du programme) sans connaître l'assembleur.

Un programmeur ou tout autre utilisateur peut utiliser n'importe quel moyen de haut niveau, jusqu'aux programmes de construction de mondes virtuels et, peut-être, sans même se douter qu'en fait l'ordinateur n'exécute pas réellement les commandes du langage dans lequel son programme est écrit, mais leur représentation transformée sous la forme de séquences ennuyeuses et ennuyeuses de commandes d'un langage complètement différent - la machine. Maintenant, imaginez qu'un tel utilisateur a un problème non standard ou que quelque chose ne va pas. Par exemple, son programme doit fonctionner avec un appareil inhabituel ou effectuer d'autres actions qui nécessitent une connaissance des principes du matériel informatique. Peu importe à quel point le programmeur est intelligent, quelle que soit la qualité du langage dans lequel il a écrit son merveilleux programme, il ne peut 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 ils prennent en charge l'accès au niveau de programmation assembleur.

Bien sûr, le temps des généralistes en informatique est révolu. Comme on dit, on ne peut pas saisir l'immensité. Mais il y a quelque chose en commun, une sorte de base sur laquelle toute formation sérieuse en informatique est construite. Il s'agit de connaissances sur les principes d'un ordinateur, son architecture et son langage d'assemblage comme reflet et incarnation de ces connaissances.

Un ordinateur moderne typique (basé sur i486 ou Pentium) comprend les composants suivants (Fig. 1).

Figure: 1. Ordinateur et périphériques

Figure: 2. Schéma fonctionnel d'un ordinateur personnel

Sur la figure (Figure 1), on peut voir que l'ordinateur est composé de plusieurs périphériques physiques, chacun d'eux étant connecté à une unité, appelée unité centrale. Logiquement parlant, il est clair qu'il joue le rôle d'une sorte de dispositif de coordination. Jetons un coup d'œil à l'intérieur de l'unité centrale (il n'est pas nécessaire d'essayer de pénétrer dans le 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 objectif fonctionnel, examinons le schéma de principe d'un ordinateur typique (Fig. 2). Il ne prétend pas être une précision inconditionnelle et vise uniquement à montrer le but, l'interconnexion et la composition typique des éléments d'un ordinateur personnel moderne.

Discutons du circuit de la Fig. 2 dans un style quelque peu non conventionnel.
Il est naturel pour une personne, lorsqu'elle rencontre quelque chose de nouveau, de rechercher des associations qui peuvent l'aider à connaître l'inconnu. Quelles associations un ordinateur provoque-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 fond de lui-même pensait créer quelque chose de similaire à lui-même. L'ordinateur a des organes de perception des informations du monde extérieur - c'est un clavier, une souris, des lecteurs magnétiques. En figue. 2 ces organes sont situés à droite des bus du système. L'ordinateur a des organes "digérant" les informations reçues - ce sont le processeur central et la mémoire vive. Et enfin, l'ordinateur possède des organes de parole qui produisent les résultats du traitement. Ce sont également certains des appareils sur la droite.

Les ordinateurs modernes, bien sûr, sont loin d'être humains. Ils peuvent être comparés à des créatures 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 élevé que vous communiquez avec un ordinateur, tout se résume à une séquence ennuyeuse et monotone d'instructions machine.
Chaque commande de machine est une sorte de stimulus pour l'excitation de l'un ou l'autre réflexe inconditionné. La réponse à ce stimulus est toujours sans ambiguïté et est «câblée» dans le bloc de micro-instruction sous la forme d'un microprogramme. Ce microprogramme met en œuvre des actions pour mettre en œuvre une commande machine, mais déjà au niveau des signaux fournis à certains circuits logiques du calculateur, contrôlant ainsi différents sous-systèmes du calculateur. C'est ce que l'on appelle le principe du contrôle par microprogramme.

Poursuivant l'analogie avec les humains, nous notons: pour qu'un ordinateur mange correctement, de nombreux systèmes d'exploitation, des compilateurs de centaines de langages de programmation, etc. ont été inventés. Mais tous ne sont, en fait, qu'un plat sur lequel de (programmes) est livré selon certaines règles de l'estomac (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 tous les programmeurs professionnels sont confrontés tôt ou tard au besoin de l'apprendre. Heureusement, le programmeur n'a pas besoin d'essayer de comprendre la signification de diverses combinaisons de nombres binaires, car dans les années 50, les programmeurs ont commencé à utiliser pour programmer un analogue symbolique d'un langage machine, qu'ils ont appelé langage d'assemblage. Ce langage reflète fidèlement toutes les fonctionnalités 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 tout ce qui précède, nous pouvons conclure que, puisque le langage d'assemblage est "natif" pour un ordinateur, 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é, ils écrivent principalement des programmes en assembleur qui devraient assurer un travail efficace avec le matériel. Parfois, les parties d'un programme qui sont critiques en termes de temps d'exécution ou de consommation de mémoire sont écrites en langage assembleur. Par la suite, ils sont formatés comme des sous-programmes et combinés avec le code de langage de haut niveau.

Il est logique de commencer à apprendre le langage d'assemblage de n'importe quel ordinateur seulement après avoir découvert quelle partie de l'ordinateur reste visible et accessible pour la programmation dans ce langage. C'est le soi-disant modèle logiciel d'un ordinateur, dont une partie est un modèle logiciel d'un microprocesseur, qui contient 32 registres d'une manière ou d'une autre disponibles pour une utilisation par un programmeur.

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

^ 16 registres d'utilisateurs;

16 registres système.

Dans les programmes en langage assembleur, les registres sont très utilisés. La plupart des registres ont des fonctionnalités spécifiques.

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

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

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

registres d'état et de contrôle:

Les drapeaux enregistrent les eflags / flags;

Le registre du pointeur de commande eip / ip.

Figure: 3. Registres d'utilisateurs des microprocesseurs i486 et Pentium

Pourquoi beaucoup de ces registres sont-ils représentés avec des séparateurs obliques? Non, ce ne sont pas des registres différents - ils font partie d'un seul grand registre 32 bits. Ils peuvent être utilisés comme des objets séparés dans le programme. Ceci est fait pour garantir l'opérabilité des programmes écrits pour les modèles 16 bits bas de gamme de microprocesseurs Intel, en commençant par i8086. Les microprocesseurs i486 et Pentium ont pour la plupart des registres 32 bits. Leur nombre, à l'exception des registres de segments, est le même que dans le i8086, mais la dimension est plus grande, ce qui se reflète dans leurs désignations - ils ont
le préfixe e (étendu).

^ Registres à usage général
Tous les registres de ce groupe vous 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 16 bits inférieurs de microprocesseurs Intel.

Listons les registres appartenant au groupe de 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) - batterie.
Il est utilisé pour stocker des données intermédiaires. Certaines commandes nécessitent ce registre;

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.
Utilisé dans les commandes qui exécutent certaines 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 la boucle, en plus de transférer le contrôle à la commande située à une certaine adresse, analyse et diminue la valeur du registre ecx / cx de un;

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; c'est implicite pour certaines commandes.

Les deux registres suivants sont utilisés pour prendre en charge les opérations dites de chaînage, c'est-à-dire les opérations qui effectuent un traitement séquentiel de chaînes d'éléments, dont chacune peut avoir une longueur de 32, 16 ou 8 bits:

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

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

Dans une architecture de microprocesseur, une structure de données telle qu'une pile est prise en charge au niveau du micrologiciel. Pour travailler avec la pile dans le système de commande du microprocesseur, il existe des commandes spéciales, et dans le modèle de logiciel du microprocesseur, il existe des registres spéciaux pour cela:

esp / sp (registre de pointeur de pile) - registre de pointeur de pile.
Contient le pointeur vers le haut de la pile dans le segment de pile actuel.

ebp / bp (registre du pointeur de base) - registre du pointeur de la base du cadre de pile.
Conçu pour organiser l'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 sûr, les données peuvent être enregistrées dans le segment de données, mais dans ce cas, pour chaque donnée stockée pendant un certain temps, une cellule de 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é d'une pile est que sa portée est réutilisable et que les données sont stockées dans la pile et récupérées à partir de là à l'aide des 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 le sous-programme, qui à son tour utilisera les registres du processeur "à ses propres fins". Le contenu original des registres est sorti de la pile au retour du sous-programme. Une autre technique courante consiste à transmettre les paramètres dont il a besoin via la pile à un sous-programme. Le sous-programme, sachant dans quel ordre les paramètres sont poussés sur la pile, peut les prendre à partir de là et les utiliser lors de son exécution. Une caractéristique distinctive de la pile est une sorte d'ordre de récupération des données qu'elle contient: à tout moment, seul l'élément supérieur est disponible dans la pile, c'est-à-dire le dernier élément poussé sur la pile. Le déchargement de 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 commençant par le bas de la pile (c'est-à-dire à partir de son adresse maximale) à des 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 entrer un segment ou former un segment séparé. Dans tous les cas, l'adresse de segment de ce segment est placée dans le registre de segment de pile SS. Ainsi, la paire de registres SS: SP décrit l'adresse de la 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 dans la pile (Fig. 4, a). Faites attention au fait que dans l'état initial, le pointeur de pile SP pointe vers une cellule située sous le bas de la pile et n'entre pas dans celle-ci.

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

Le chargement dans la pile est effectué par une commande spéciale de pile, push (push). Cette commande 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 sauvegarder 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. Vous pouvez voir que le pointeur de pile est décalé de deux octets vers le haut (vers les adresses inférieures) et l'opérande spécifié dans la commande push est écrit à cette adresse. La charge suivante sur la commande stack, par exemple

mettra la pile dans l'état illustré à la Fig. 1.10, ch. La pile va maintenant stocker deux éléments, et seul celui du haut, vers lequel pointe le pointeur de pile SP, sera disponible. Si, après un certain temps, nous devons restaurer le contenu original des registres stockés sur la pile, nous devons exécuter les commandes pour décharger de la pile pop (pop):

pop DS
pop AX

Quelle doit être la taille de la pile? Cela dépend de la façon dont il est utilisé dans le programme. Si, par exemple, vous prévoyez de stocker un tableau de 10 000 octets sur la pile, la pile doit avoir au moins cette taille. Il faut garder à l'esprit que dans certains cas, la pile est automatiquement utilisée par le système, en particulier, lorsque la commande d'interruption int 21h est exécutée. Avec cette commande, le processeur pousse d'abord l'adresse de retour sur la pile, puis DOS y envoie 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, elle 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 certainement suffisant.

^ La structure d'un programme en assemblage

Un programme en langage assembleur est une collection de blocs de mémoire appelés segments de mémoire. Un programme peut être constitué d'un ou plusieurs de ces segments de bloc. Chaque segment contient un ensemble de phrases de langue, dont chacune occupe une ligne distincte de code de programme.

Les phrases d'assemblage sont de quatre types:

commandes ou instructions qui sont des analogues symboliques des instructions de la machine. Pendant la traduction, les instructions assembleur sont converties en commandes correspondantes du jeu d'instructions du microprocesseur;

macros - phrases du texte du programme qui sont formées d'une certaine manière, qui sont remplacées par d'autres phrases pendant la diffusion;

directives qui indiquent au traducteur assembleur d'effectuer certaines actions. Les directives n'ont pas d'analogue dans la représentation de la machine;

lignes de commentaires contenant des caractères quelconques, y compris les lettres de l'alphabet russe Les commentaires sont ignorés par le traducteur.

^ Syntaxe de l'assembleur

Les phrases qui composent le 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. La meilleure façon de faire est d'utiliser une description formelle de la syntaxe du langage, comme les règles de grammaire. Les manières les plus courantes de décrire un langage de programmation de cette manière sont les diagrammes de syntaxe et les formes étendues de Backus-Naur. Pour une utilisation pratique, les diagrammes de syntaxe sont plus pratiques. Par exemple, la syntaxe des phrases assembleur peut être décrite à l'aide des diagrammes de syntaxe illustrés dans les figures suivantes.

Figure: 5. Format de la phrase de l'assembleur

Figure: 6. Format des directives

Figure: 7. Format des commandes et des macros

Dans ces chiffres:

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

name est un identifiant qui distingue cette directive des autres directives du même nom. En raison du traitement d'une certaine directive par l'assembleur, ce nom peut se voir attribuer certaines caractéristiques;

un code d'opération (COP) et une directive sont des désignations mnémotechniques de l'instruction machine, de la macro ou de la directive de traduction correspondante;

les opérandes sont des parties d'une instruction, d'une macro ou d'une directive d'assembleur qui désignent les objets à manipuler. Les opérandes de l'assembleur sont décrits par des expressions avec des constantes numériques et textuelles, des étiquettes et des identificateurs de variable utilisant des signes d'opération et des mots réservés.

^ Comment utiliser les diagrammes de syntaxe? C'est très simple: il suffit de rechercher puis de passer de l'entrée du diagramme (à gauche) à sa sortie (à droite). Si un tel chemin existe, alors la phrase ou la construction est syntaxiquement correcte. S'il n'y a pas de tel chemin, le compilateur n'acceptera pas cette construction. Lorsque vous travaillez avec des diagrammes de syntaxe, faites attention au sens de traversée, 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 de syntaxe 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 du programme sont:

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

Nombres de 0 à 9;

Signes?, @, $, _, &;

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

Les phrases d'assembleur sont formées de jetons, qui sont des séquences syntaxiquement inséparables de caractères de langage valides qui ont un sens pour un traducteur.

Les jetons sont:

les identificateurs sont des séquences de caractères valides utilisées pour désigner des objets 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. Lettres de l'alphabet latin, chiffres et quelques caractères spéciaux - _,?, $, @ Peuvent être utilisés comme symboles. L'identifiant ne peut pas commencer par un caractère numérique. La longueur de l'identifiant peut aller jusqu'à 255 caractères, bien que le traducteur n'accepte que les 32 premiers et ignore le reste. La longueur des identificateurs possibles peut être ajustée à l'aide de l'option de ligne de commande mv. De plus, il est possible de dire au traducteur de faire la distinction entre les majuscules et les minuscules, ou d'ignorer leur différence (ce qui est fait par défaut).

^ Commandes de l'assembleur.

Les commandes de l'assembleur révèlent la possibilité de transférer leurs besoins vers 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 programmables sont rarement aussi faciles. 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 de 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 instructions pour différents processeurs, mais nous considérerons un certain nombre d'instructions 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 un échantillon d'une table qui reflète la structure du registre eflags:

La dernière ligne de ce tableau répertorie les valeurs d'indicateur une fois la commande exécutée. Dans ce cas, les désignations suivantes sont utilisées:

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

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

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

L'indicateur n'est pas défini après l'exécution de la commande;

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

Les conventions suivantes sont utilisées pour représenter les opérandes dans les diagrammes de syntaxe:

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

m8, m16, m32, m48 - octet, mot, double mot ou opérande mémoire 48 bits;

i8, i16, i32 - un opérande immédiat d'octet, de mot ou de 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
(Une addition)

Une addition

^ Schéma de commande:

ajouter une destination, une source

Objectif: ajout de deux opérandes source et destination en octets, mot ou double mot.

Algorithme de travail:

ajoutez les opérandes source et destination;

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

définir des drapeaux.

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

Application:
La commande add est utilisée pour ajouter 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 est en dehors des limites de l'opérande du récepteur (un débordement se produit), alors cette situation doit être prise en compte en analysant le drapeau cf et l'utilisation ultérieure possible de la commande adc. Par exemple, ajoutez les valeurs dans ax et ch. L'ajout doit prendre en compte la possibilité de débordement.

Registre plus registre ou mémoire:

| 000000dw | modregr / rm |

Registre AX (AL) plus valeur immédiate:

| 0000010w | --data-- | données si w \u003d 1 |

Registre ou mémoire plus valeur immédiate:

| 100000sw | mod000r / m | --data-- | données si BW \u003d 01 |

APPEL
(APPEL)

Appeler une procédure ou une tâche

^ Schéma de commande:

Objectif:

transfert de contrôle vers une procédure proche ou distante avec stockage de l'adresse du point de retour dans la pile;

commutation de tâches.

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

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

Etiquette distante - le contenu des pointeurs de commande eip / ip et cs est poussé sur la pile. Ensuite, de nouvelles valeurs d'adresse correspondant à l'étiquette éloignée sont chargées dans les mêmes registres;

R16, 32 ou m16, 32 - définissent un registre ou un emplacement mémoire contenant des décalages dans le segment d'instruction actuel vers lequel 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 de 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 indicateurs

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

À propos du code objet (quatre formats):

Adressage de segment direct:

| 11101000 | disp-low | diep-high |

Adressage indirect dans un segment:

| 11111111 | mod010r / m |

Adressage indirect entre segments:

| 11111111 | mod011r / m |

Adressage direct entre segments:

| 10011010 | offset-bas | offset-haut | seg-bas | seg-haut |

CMP
(Opérandes CoMPare)

Comparaison des opérandes

^ Schéma de commande:

cmp opérande1, opérande2

Objectif: comparaison de deux opérandes.

Algorithme de travail:

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

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

Application:
Cette commande permet de soustraire deux opérandes sans changer les opérandes. Les indicateurs sont définis en fonction des résultats de l'exécution de la commande. La commande cmp est utilisée avec les commandes de branchement conditionnel et la commande octet par valeur setcc.

À propos du code objet (trois formats):

Registre ou mémoire avec registre:

| 001110dw | modregr / m |

Valeur directe avec le registre AX (AL):

| 0011110w | --données-- | données si w \u003d 1 |

Valeur immédiate avec registre ou mémoire:

| 100000sw | mod111r / m | --data-- | données si sw \u003d 0 |

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

Diminuer l'opérande de un

^ Schéma de commande:

opérande dec

Objectif: diminuer la valeur d'un opérande en mémoire ou dans un registre de 1.

Algorithme de travail:
la commande soustrait 1 de l'opérande. État des drapeaux après l'exécution de la commande:

Application:
La commande dec permet de décrémenter de un la valeur d'un octet, d'un mot, d'un double mot en mémoire ou d'un registre. Cependant, notez que la commande n'affecte pas l'indicateur cf.

Inscription: | 01001reg |

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

DIV
(DIVISE non signé)

Division non signée

Schéma de commande:

diviseur de division

Objectif: effectuer l'opération de division de deux valeurs binaires non signées.

^ Algorithme de travail:
Pour la commande, vous devez spécifier deux opérandes - le dividende et le diviseur. Le dividende est défini implicitement et sa taille dépend de la taille du diviseur, qui est spécifiée dans la commande:

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

si le diviseur est un mot, alors le dividende doit être situé dans une paire de registres dx: ax, avec la partie la moins significative du dividende en ax. Après l'opération, le quotient est placé en ax et le reste en dx;

si le diviseur est un double mot, alors le dividende doit être situé dans la paire de registres edx: eax, avec la partie la moins significative du dividende dans eax. Après l'opération, le quotient est placé dans eax et le reste est placé dans edx.

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

Application:
La commande effectue une division entière des opérandes avec la sortie du 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.

À propos du code objet:

| 1111011w | mod110r / m |

INT
(Interrompre)

Appel de la routine de service d'interruption

^ Schéma de commande:

int numéro_interruption

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

^ Algorithme de travail:

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

remettre à zéro les indicateurs if et tf;

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

^ État des drapeaux après l'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 rend très pratique l'utilisation dans divers débogueurs logiciels pour définir des points d'arrêt en remplaçant le premier octet de toute commande. Lorsque le microprocesseur rencontre une commande avec un opcode de 0cch dans la séquence de commandes, il appelle le gestionnaire d'interruption avec le vecteur numéro 3, qui est utilisé pour communiquer avec le débogueur logiciel.

La deuxième forme de la commande prend deux octets, a un opcode de 0cdh et vous permet de lancer un appel à une routine de service d'interruption avec un numéro de vecteur compris entre 0 et 255. Les caractéristiques du transfert de contrôle, comme indiqué, dépendent du mode de fonctionnement du microprocesseur.

A propos du code objet (deux formats):

Inscription: | 01000reg |

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

JCC
JCXZ / JECXZ
(Sauter si condition)

(Sauter si CX \u003d Zéro / Sauter si ECX \u003d Zéro)

Sauter si la condition est remplie

Sauter si CX / ECX est nul

^ Schéma de commande:

étiquette jcc
étiquette jcxz
étiquette jecxz

Objectif: transition dans le segment actuel des commandes en fonction d'une certaine condition.

^ Algorithme de commandes (sauf pour jcxz / jecxz):
Vérification de l'état des drapeaux en fonction du code d'opération (il reflète la condition vérifiée):

si la condition vérifiée est vraie, passez à la cellule indiquée par l'opérande;

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

Algorithme de la commande jcxz / jecxz:
Vérification de la condition d'égalité à zéro du contenu du registre ecx / cx:

si la condition vérifiée

La programmation au niveau de l'instruction machine est le niveau minimum auquel la programmation est possible. Le système d'instructions de la machine doit être suffisant pour effectuer les actions requises, en donnant des instructions au matériel de l'ordinateur.

Chaque instruction machine se compose de deux parties:

  • salle d'opération - déterminer «quoi faire»;
  • opérande - définition des objets de traitement, "que faire avec".

Une instruction machine à microprocesseur écrite en langage d'assemblage est une seule ligne avec la forme syntaxique suivante:

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

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

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, la barre oblique inverse est utilisée: \\.

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

Exemples de lignes de code:

Compter db 1 ; Nom, directive, un opérande
mov eax, 0 ; Commande, deux opérandes
cbw; Équipe

Mots clés

Étiquette en langage d'assemblage peut contenir les caractères 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 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 nombre). La longueur maximale de l'étiquette est de 31 caractères. Toutes les étiquettes écrites sur une ligne qui ne contient pas de directive assembleur doivent se terminer par deux points:.

Commandes

Équipe indique au traducteur quelle action le microprocesseur doit entreprendre. Dans un segment de données, une commande (ou directive) définit un champ, une zone de travail ou une constante. Dans le segment de code, l'instruction définit l'action, comme le transfert (mov) ou l'addition (add).

Directives

L'assembleur dispose d'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 instruction machine ou un opérateur d'un langage de programmation est exécuté.
Une instruction peut avoir un ou deux opérandes, ou pas du tout. Le nombre d'opérandes est spécifié implicitement par le code de commande.
Exemples:

  • Aucune nouvelle opérande; Retour
  • Un opérande inc ecx; Augmenter ecx
  • Deux opérandes ajoutent eax, 12; Ajouter 12 à eax

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

Les opérandes peuvent être

  • identifiants;
  • chaînes de caractères entre guillemets simples ou doubles;
  • entiers en notation binaire, octale, décimale ou hexadécimale.
Identifiants

Identifiants - séquences de caractères valides utilisées pour désigner des objets programme tels que des opcodes, des noms de variables et des noms d'étiquettes.

Règles d'écriture des identifiants.

  • L'identifiant peut être un ou plusieurs caractères.
  • Les lettres de l'alphabet latin, les chiffres et certains caractères spéciaux peuvent être utilisés comme symboles: _,?, $, @.
  • L'identifiant ne peut pas commencer par un caractère numérique.
  • L'identifiant 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; ... Dans ce cas, tout ce qui est écrit après le symbole point-virgule et jusqu'à la fin de la ligne est un commentaire. L'utilisation de commentaires dans le programme améliore sa clarté, en particulier lorsque le but du jeu d'instructions n'est pas clair. Un commentaire peut contenir tous les caractères imprimables, y compris un espace. Un commentaire peut s'étendre sur toute la ligne ou suivre une commande sur la même ligne.

La structure d'un programme d'assemblage

Un programme écrit en langage d'assemblage peut être composé 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 d'assemblage complet doit inclure un module principal, ou principal, à partir duquel démarrer son exécution. 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 d'assemblage «ne rien faire»:

686P
.MODÈLE APPARTEMENT, STDCALL
.LES DONNÉES
.CODE
DÉBUT:

RET
FIN DEBUT

Ce programme ne contient qu'une seule instruction de microprocesseur. Cette commande est RET. Il garantit la fin correcte du programme. En général, cette commande est utilisée pour quitter une procédure.
Le reste du programme est lié au travail du traducteur.
.686P - Commandes en mode protégé Pentium 6 (Pentium II) 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 informe le 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é dans le système d'exploitation Windows. stdcall
.DATA - segment de programme contenant des données.
.CODE - un bloc du programme contenant le code.
START est une étiquette. En langage assembleur, les étiquettes jouent un grand rôle, ce qui n'est pas le cas dans les langages modernes de haut niveau.
END START - la fin du programme et un message au traducteur indiquant que le programme doit être lancé à partir de l'étiquette START.
Chaque module doit contenir une directive END pour marquer la fin du code source du programme. 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 démarre. Si le programme contient un module, l'étiquette après la directive END peut être omise.

Commandes de l'assembleur (conférence)

PLAN DE LECTURE

1. Les principaux groupes d'opérations.

Pentium.

1. Groupes d'opérations de base

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

Opérations de réexpédition,

Opérations arithmétiques,

Opérations logiques,

Opérations de quart,

Tester les opérations de comparaison,

Opérations sur les bits,

Opérations de contrôle 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émotechniques (codes mnémoniques) sont généralement utilisées, qui sont utilisées pour définir la commande lors de la programmation en langage d'assemblage. Pour différentes versions d'Assembler, les codes mnémotechniques de certaines commandes peuvent différer. Par exemple, pour une commande pour appeler un sous-programme, le code mnémonique est utiliséAPPEL ou JSR ("Sauter à Sous-routine”). Cependant, les codes mnémotechniques de la plupart des commandes pour les principaux types de microprocesseurs coïncident ou diffèrent légèrement, car ce sont des abréviations des mots anglais correspondants qui déterminent l'opération en cours. Considérez les codes mnémotechniques des commandes adoptées pour les processeursPentium.

Commandes de transfert. L'équipe principale de ce groupe est l'équipeMOV , qui assure le transfert de données entre deux registres ou entre un registre et une cellule mémoire. Certains microprocesseurs mettent en œuvre le transfert entre deux cellules de mémoire, ainsi que le transfert en masse du contenu de plusieurs registres depuis la mémoire. Par exemple, les microprocesseurs de la famille 68xxx de Motorola exécuter la commandeBOUGE TOI , assurant le transfert d'une cellule mémoire à une autre, et la commandeMOVEM , qui écrit en mémoire ou charge à partir de 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 retrait EN DEHORS transférer des données d'un registre de processeur vers un appareil externe ou recevoir des données d'un appareil externe vers un 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 de commandes spéciales pour accéder aux périphériques externes. Dans ce cas, l'entrée et la sortie de données dans le système sont effectuées à l'aide de la commandeMOV , dans lequel l'adresse du périphérique d'interface requis est définie. Ainsi, un dispositif externe est adressé comme une cellule de mémoire, et une certaine section est allouée dans l'espace d'adressage, dans lequel se trouvent les adresses des dispositifs d'interface (ports) connectés au système.

Commandes arithmétiques. Les commandes principales de ce groupe sont les commandes d'addition, de soustraction, de multiplication et de division, qui ont plusieurs options. Commandes d'addition AJOUTER et soustraction SOUS effectuer les opérations appropriées aveccobsédé par deux registres, un registre et un emplacement mémoire, ou en utilisant un opérande immédiat. Commandes UN D C , SB B l'addition et la soustraction sont effectuées en tenant compte de la valeur d'attributC, qui est défini lorsque le transfert est formé lors de l'opération précédente. A l'aide de ces commandes, l'addition séquentielle des opérandes est réalisée, dont le nombre de bits dépasse la capacité du processeur. Équipe NEG change le signe de l'opérande en le traduisant en un code complémentaire.

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 L'un des opérandes est toujours alloué dans un registre, l'autre peut être dans un registre, un emplacement mémoire ou un opérande direct. Le résultat de l'opération se trouve dans le registre. Lors de la multiplication (commandesMUL , IMUL ), le résultat est un résultat à deux chiffres, pour lequel deux registres sont utilisés. Lors de la division (commandesDIV , IDIV ) comme dividende, un opérande à deux chiffres est utilisé, situé dans deux registres, et par conséquent, le quotient et le reste sont écrits dans deux registres.

Commandes booléennes ... Presque tous les microprocesseurs effectuent des opérations logiques ET, OU, OU exclusif, qui sont effectuées sur les mêmes bits des opérandes à 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 Shift... Les microprocesseurs effectuent des décalages arithmétiques, logiques et cycliques des opérandes adressés d'un ou plusieurs bits. L'opérande décalé peut être 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 retenue est généralement impliqué dans la mise en œuvre du quart de travailC dans le registre d'état (SRou EFLAGS), qui contient le dernier bit de l'opérande, qui est déplacé hors du registre ou de la cellule mémoire.

Comparer et tester des équipes ... La comparaison des opérandes se fait généralement à l'aide de la commandeCMP , qui soustrait les opérandes avec le réglage des valeurs 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 sont pas modifiées. Une analyse ultérieure des valeurs de caractéristiques obtenues vous permet de déterminer la valeur relative (\u003e,<, =) операндов со знаком или без знака. Использование различных способов адресации позволяет производит сравнение содержимого двух регистров, регистра и ячейки памяти, непосредственно заданного операнда с содержимым регистра или ячейки памяти.

Certains microprocesseurs exécutent la commande de test TST , qui est une variante à un seul opérande de la commande compare. L'exécution de cette commande définit le N, Z selon le signe et la valeur (égale ou non égale à zéro) de l'opérande adressé.

Commandes d'opérations sur les bits ... Ces commandes définissent la valeur d'attributC dans le registre d'état en fonction de la valeur du bit testébn dans l'opérande adressé. Dans certains microprocesseurs, selon le résultat du test du bit, le signe est définiZ... Numéro de bit de testn est 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 garde la valeur de ce bit inchangée. B T S après le test définit la valeur bn\u003d 1 et la commande B T C - valeur bn\u003d 0 commande B T C inverse la valeur du bit bn après l'avoir testé.

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

- commandes de transfert de contrôle inconditionnelles;

- commandes de saut conditionnel;

- des équipes d'organisation des cycles de programme;

- commandes d'interruption;

- commandes pour modifier les fonctionnalités.

Le transfert de contrôle inconditionnel est effectué par la commandeJMP qui se charge dans le compteur de programmesPC nouveau contenu, qui est l'adresse de la prochaine commande à exécuter. Cette adresse est soit directement spécifiée dans la commandeJMP (adressage direct), ou calculé comme la somme du contenu actuelPC et l'offset de commande, qui est un nombre signé (adressage relatif). CarPC contient l'adresse de la commande de programme suivante, puis la dernière méthode définit le décalage de l'adresse de saut par rapport à l'adresse suivante d'un nombre spécifié d'octets. Avec un décalage positif, la transition vers les commandes de programme suivantes, avec un décalage négatif - vers les précédentes.

Un appel de sous-programme est également effectué par transfert inconditionnel de contrôle à l'aide de la commandeAPPEL (ou JSR ). Cependant, dans ce cas, avant de charger dansPC nouveau contenu qui fixe l'adresse de la première commande du sous-programme, il est nécessaire de conserver sa valeur actuelle (l'adresse de la commande suivante) afin d'assurer un retour au programme principal (ou au sous-programme précédent lors de l'imbrication des sous-programmes) après l'exécution du sous-programme. Les commandes de branche conditionnelles (branches de programme) sont chargées dansPC nouveau contenu si certaines conditions sont remplies, qui sont généralement définies en fonction de la valeur actuelle de divers signes 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 fonctionnalités permettent l'écriture - la lecture du contenu du registre d'état, qui stocke les fonctionnalités, ainsi que la modification des valeurs des fonctionnalités individuelles. Par exemple, dans les processeurs Pentium, les commandes sont implémentées LAHF et SAHF qui chargent l'octet de poids faible contenant les signes du registre d'état EFLAG à l'octet bas du registre EAX et complétant l'octet de poids faible EFLAGS du registre E AX.. Équipes CLC, STC effectuer le paramétrage des valeurs de l'attribut de transfert CF \u003d 0, CF \u003d 1 et de la commande CMC provoque l'inversion de la valeur de cet attribut. Étant donné que les fonctionnalités déterminent le déroulement de l'exécution du programme pendant les sauts conditionnels, les commandes de changement de fonctionnalité sont généralement utilisées pour contrôler le programme.

Commandes CPU ... Ce groupe comprend des 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 met le processeur dans un état d'arrêt, dont la sortie se produit lorsqu'un signal d'interruption ou de redémarrage est reçu (Réinitialiser). Équipe NOP (Commande "Vide"), qui ne provoque l'exécution d'aucune opération, est utilisée pour implémenter des retards de programme ou combler les lacunes formées dans le programme.

Commandes spéciales CLI, STI désactiver et activer le service des demandes d'interruption. Dans les processeursPentium le bit de contrôle (drapeau) est utilisé pour celaSI dans le registre EFLAGS.

De nombreux microprocesseurs modernes exécutent une commande d'identification qui permet à un utilisateur ou à un autre appareil d'obtenir des informations sur le type de processeur utilisé dans un système donné. Dans les processeurs Pentuim la commande est utilisée pour cela CPUID , lors de l'exécution, les données nécessaires sur le processeur vont aux registres EAX,EBX,ECX,EDX et peut ensuite être lu par l'utilisateur ou le système d'exploitation.

En fonction des modes de fonctionnement mis en œuvre par le processeur et des types spécifiés de données en cours de traitement, l'ensemble des commandes exécutables peut s'étendre considérablement.

Certains processeurs effectuent des opérations arithmétiques avec des nombres décimaux binaires ou exécutent des commandes spéciales pour corriger le résultat lors du traitement de ces nombres. De nombreux processeurs hautes performances incluentFPU - unité de traitement des nombresc Point flottant.

Un certain nombre de processeurs modernes implémentent le traitement de groupe de plusieurs entiers ou nombresc Virgule flottante avec une seule instructionSIMD ("Instruction unique - Données multiples ») -« Une commande - Beaucoup de données ». L'exécution simultanée d'opérations sur plusieurs opérandes améliore considérablement les performances du processeur lorsque vous travaillez avec des données vidéo et audio. Ces opérations sont largement utilisées pour le traitement d'image, les signaux audio et d'autres applications. Pour effectuer ces opérations, des blocs spéciaux ont été introduits dans les processeurs qui implémentent les ensembles d'instructions correspondants, qui dans divers types de processeurs (Pentium, Athlon) ont été nommésMMX (“ Milti- Extension multimédia ”) - Extension multimédia,SSE («Streaming SIMD Extension») - Streaming SIMD - extension, “3 Extension - Expansion 3D.

Une caractéristique des processeurs de l'entrepriseIntel , à partir du modèle 80286, il existe un 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 adopté.

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. Opérateurs du programme en assembleur ……………………………………

    1. Commandes du langage d'assemblage

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. Supposons la directive

3.2.3 Directive de segmentation simplifiée

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

5. Commandes d'envoi de données …………………………………………….

    5.1 Commandes générales

    5.2 Commandes pour travailler avec la pile

5.3 Commandes d'E / S

5.4 Commandes de transfert d'adresse

5.5 Commandes d'envoi de drapeaux

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

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 Routines 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 Table de distribution des fichiers

11.3 E / S disque

11.3.1 Ecriture d'un fichier sur le disque

11.3.1.1 Données au format ASCIIZ

11.3.1.2 Numéro de fichier

11.3.1.3 Créer un fichier disque

11.3.2 Lire un fichier disque

introduction

Le langage d'assemblage est une représentation symbolique d'un 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 vraiment résoudre les problèmes liés au matériel (ou même les problèmes liés au matériel tels que l'amélioration des performances du programme) sans connaître l'assembleur.

L'assembleur est une forme pratique de commandes directement pour les 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 PC. Ainsi, le langage d'assemblage 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 du langage 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 du 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 des problèmes de programmation en langage d'assemblage pour les ordinateurs basés sur des microprocesseurs d'Intel.

Ce tutoriel s'adresse à tous ceux qui s'intéressent à l'architecture des processeurs et aux bases de la programmation en langage assembleur, principalement les développeurs de logiciels.

    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 d'ordinateur spécifique.

Le concept d'architecture informatique comprend:

    schéma fonctionnel de l'ordinateur;

    les moyens et méthodes d'accès aux éléments du schéma de principe de l'ordinateur;

    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 informatiques;

    formats d'instructions machine;

    interrompre la manipulation.

Les principaux éléments du matériel informatique: l'unité centrale, le clavier, les périphériques d'affichage, les lecteurs de disque, les périphériques d'impression (imprimante) et diverses communications. L'unité centrale se compose d'une carte mère, d'un bloc d'alimentation et de logements d'extension pour cartes supplémentaires. La carte système contient un microprocesseur, une mémoire morte (ROM), une mémoire vive (RAM) et un coprocesseur.

      Registres.

A l'intérieur du microprocesseur, les informations sont contenues dans un groupe de 32 registres (16 utilisateurs, 16 systèmes), dans une certaine mesure disponibles pour une utilisation par le programmeur. Étant donné que le didacticiel est consacré à la programmation du microprocesseur 8088-i486, il est plus logique de commencer ce sujet en discutant des registres internes du microprocesseur disponibles pour 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 d'indicateur EFLAGS / FLAGS et registre de pointeur d'instruction EIP / IP.

La barre oblique marque les parties d'un seul registre 32 bits. 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 haut des parties 16 bits des registres.

        Registres à usage général.

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

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 de répétition de boucle.

EDX / DX / DH / DL - registre de données (registre de données), utilisé pour stocker des données intermédiaires. Il est obligatoire dans certaines commandes.

Tous les registres de ce groupe permettent d'accéder à leurs parties «inférieures». Seules les parties inférieures 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 ligne qui permettent le traitement séquentiel de chaînes d'éléments d'une longueur de 32, 16 ou 8 bits, utilisez:

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

EDI / DI (registre d'index de distination) - indice destinataire (bénéficiaire). Contient l'adresse actuelle dans la chaîne de réception.

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

ESP / SP (registre de poINTeur de pile) - s'inscrire aiguille empiler... Contient le 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 a six registres de segment: 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 segments sont utilisés pour indiquer les segments 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 (code segment register) - 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 des données traitées par le programme. Pour accéder à ce segment, utilisez le registre DS (data segment register) - registre de données de segmentqui stocke l'adresse du segment de données du programme en cours.

    Segment de pile. Ce segment représente une zone de mémoire appelée 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 segment de pilecontenant l'adresse du segment de pile.

    Segment de données supplémentaire. Les données traitées peuvent être dans trois segments de données supplémentaires. Par défaut, les données sont supposées être 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 de remplacement de segment spéciaux dans la commande. Les adresses des segments de données supplémentaires doivent être contenues dans ES, GS, FS (registres de segments de données extensibles).

        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 commandes sont actuellement chargées dans le pipeline. Il:

Registre de pointeur de commande EIP / IP;

    enregistrer les drapeaux EFLAGS / FLAGS.

En utilisant 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'instructions) - aiguille équipes... Le registre EIP / IP a une largeur de 32 ou 16 bits et contient le décalage de la prochaine instruction exécutée 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 commandes de saut.

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

1.1.3 Registre des drapeaux

Le registre des drapeaux est de 32 bits et porte le nom EFLAGS (figure 1). Les bits individuels du registre ont un objectif fonctionnel spécifique et sont appelés indicateurs. 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'indicateur 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 corrigent certaines propriétés de leur résultat (par exemple, s'il est égal à zéro). Les autres indicateurs sont appelés indicateurs d'état; ils changent du programme et affectent le comportement ultérieur du processeur (par exemple, bloquer les interruptions).

Indicateurs de condition:

CF (porter le drapeau) - porter le drapeau... Prend la valeur 1 si, lors de l'ajout de nombres entiers, une unité de retenue apparaissait qui ne "cadrait" 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, un bit qui a dépassé la grille de bits est défini dans CF. CF capture également les fonctionnalités de la commande de multiplication.

OF (indicateur de débordement) - indicateur de débordement... Il est mis à 1 si, lors de l'addition ou de la soustraction d'entiers signés, on obtient un résultat supérieur en valeur absolue à la valeur admissible (la mantisse a débordé et elle a "grimpé" dans le bit de signe).

ZF (drapeau zéro) - drapeau zéro... Il est mis à 1 si le résultat de la commande est égal à 0.

SF (indicateur SIgn) - drapeau signe... Il est mis à 1 si l'opération sur les nombres signés aboutit à un résultat négatif.

PF (indicateur 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 lors des opérations d'E / S.

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

Indicateurs d'état:

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

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

Drapeau système:

IF (indicateur INTerrupt) - indicateur d'interruption... Si IF \u003d 0, le processeur cesse de répondre aux interruptions entrantes; si IF \u003d 1, le verrou d'interruption est libéré.

TF (indicateur de piège) - indicateur de trace... Si TF \u003d 1, après l'exécution de chaque instruction, le processeur effectue une interruption (avec le numéro 1), qui peut être utilisée lors du débogage du 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 virtuAL 8086) - drapeau 8086 virtuel. 1-processeur fonctionne en mode virtuel 8086.0- le processeur fonctionne en mode réel ou protégé.

AC (contrôle d'alignement) - indicateur de contrôle d'alignement. Conçu pour activer 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 d'adresses physiques va de 0 à 4 Go. Le mécanisme de gestion de la mémoire est entièrement basé sur le 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 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 associée à l'organisation de la mémoire virtuelle, qui permet aux programmes d'utiliser un espace mémoire supérieur à la quantité de mémoire physique. Pour un microprocesseur Pentium, la taille de 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 développés pour les premiers modèles de processeurs.

    Mode protégé. En mode protégé, il devient possible de multitâche de traitement de l'information, de protection de la mémoire à l'aide d'un mécanisme de privilège à quatre niveaux et de sa pagination.

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

La segmentation est un mécanisme d'adressage qui permet à plusieurs espaces d'adressage indépendants d'exister. Un segment est un bloc de mémoire indépendant et supporté par le matériel.

Chaque programme dans le cas général peut être constitué de n'importe quel nombre de segments, mais il a un accès direct à trois principaux: code, données et pile - et d'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 correspondants. A l'intérieur d'un segment, le programme accède linéairement aux adresses relatives au début du segment, c'est-à-dire à partir de l'adresse 0 et se terminant par 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 de changement de l'adresse physique est de 0 à 1 Mo. La taille maximale du segment est de 64 Ko. Lorsque vous faites 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 d'une 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épart du segment de mémoire auquel appartient la cellule, et offset est l'adresse 16 bits de cette cellule, comptée à partir du début de cette mémoire segment (la valeur 16 * segment + offset donne l'adresse absolue de la cellule). Si, par exemple, le registre CS stocke la valeur 1234h, alors la paire d'adresses 1234h: 507h définit une adresse absolue égale à 16 * 1234h + 507h \u003d 12340h + 507h \u003d 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 un décalage, et le second - un segment, et chacun de ces mots est présenté à son tour en une forme «inversée». Par exemple, la paire 1234h: 5678h s'écrira comme ceci: | 78 | 56 | 34 | 12 |.

Ce mécanisme de formation d'une adresse physique permet de rendre le logiciel relocalisable, c'est-à-dire qu'il ne dépend pas des adresses spécifiques de son chargement en RAM.

Sujet 2.5 Bases de la programmation du processeur

Au fur et à mesure que la durée du programme augmente, il devient plus difficile de mémoriser des codes pour diverses opérations. Les désignations mnémotechniques fournissent une certaine aide à cet égard.

Le langage de codage symbolique des commandes est appelé assembleur.

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

Assemblage s'appelle la conversion d'un programme à partir du langage d'assemblage, c'est-à-dire la préparation d'un programme en langage machine en remplaçant les noms symboliques d'opérations par des codes machine, et les adresses symboliques par des nombres absolus ou relatifs, ainsi que l'inclusion de programmes de bibliothèque et la génération de séquences de commandes symboliques en spécifiant des paramètres spécifiques dans les micro-instructions. Ce programme est généralement situé 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 biunivoque entre les déclarations du langage d'assemblage 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 d'algorithmes plus rationnelles pour résoudre des problèmes appliqués;

La possibilité d'afficher et de corriger les programmes exécutables avec les extensions .exe et.com compilés à partir de n'importe quel langage de haut niveau en cas de perte des programmes d'origine (en appelant les programmes spécifiés dans le débogueur du programme DEBUG et en décompilant leur affichage dans l'assembly Langue);

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

Pour la mise en œuvre des procédures incluses dans le programme principal sous forme de fragments séparés au cas où elles ne pourraient pas être implémentées ni dans le langage de haut niveau utilisé, ni à l'aide des procédures de service OS.

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 d'assemblage est composé de caractères ASCII.

Seuls les nombres entiers. Distinguer:

Les nombres binaires se terminent par la lettre B;

Nombres décimaux, se terminant par la lettre D;

Nombres hexadécimaux, se terminant par la lettre N.

RAM, registres, pré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. Il est plus facile de programmer dans cette langue. Un programme en langage assembleur utilise plus rationnellement les capacités d'une machine particulière (plus précisément, MP) qu'un programme dans un langage de haut niveau (ce qui est plus facile pour un programmeur qu'un assembleur). Considérez les principes de base de la programmation dans les langages orientés machine en utilisant l'exemple du langage assembleur pour MP KR580VM80. Une technique courante est utilisée pour la programmation dans le langage. Les techniques spécifiques d'enregistrement des programmes sont associées à l'architecture et au système de commande du MT cible.

Modèle de programme d'un système à microprocesseur basé sur MP KR580VM80

Le modèle logiciel du MPS conformément à la figure 1

Mémoire des ports MP

S Z AC P C

Image 1

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

ET- Accumulateur de registre 8 bits. C'est le registre principal de MP. Toute opération effectuée dans l'ALU implique de 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 (RON) 8 bits. 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, les paires BC, DE, HL sont formées à partir des registres et le double registre 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 ont une propriété spéciale, qui est 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 cinq signes du résultat de l'exécution d'opérations arithmétiques et logiques dans le MP sont stockés. Format FL comme illustré

Bit C (CY - report) - report, mis à 1 s'il y avait un report du bit le plus significatif de l'octet lors de l'exécution d'opérations arithmétiques.

Bit P (parité) - parité, mis à 1 si le nombre de uns dans les bits du résultat est pair.

Le bit AC est un report supplémentaire, destiné à stocker la valeur de report du quartet inférieur du résultat.

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

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

SP–- pointeur de pile, registre 16 bits, destiné à stocker l'adresse de la cellule mémoire où le dernier octet entré dans la pile a été écrit.

RS - compteur de programme (compteur de programme), registre de 16 bits, utilisé pour stocker l'adresse de la prochaine commande à exécuter. Le contenu du compteur de commandes est automatiquement incrémenté de 1 immédiatement après l'échantillonnage de l'octet de commande suivant.

La zone de mémoire initiale de l'adresse 0000H - 07FF contient le programme de commande et les programmes de démonstration. C'est la zone ROM.

0800 - 0АFF - zone d'adresse pour rédiger les 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).

Une pile est une zone de RAM spécialement organisée conçue pour stocker temporairement des données ou des adresses. Le dernier numéro poussé sur la pile apparaît en premier. Le pointeur de pile stocke l'adresse de la dernière cellule de la pile où les informations sont écrites. Lorsqu'un sous-programme est appelé, l'adresse de retour au programme principal est automatiquement enregistré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 sauvegardé sur la pile, et à la fin du sous-programme, ils sont restaurés à partir de la pile.

Format des données et structure des commandes en langage assembleur

La mémoire du 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 la ROM et 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 plus significatif est le bit 7.

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

Format de commande

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

Le premier octet de la commande contient l'opcode mnémotechnique.

Il définit le format de la commande et les actions qui doivent être effectuées par le MT sur les données pendant son exécution, ainsi que le mode d'adressage, et peut également contenir des informations sur la recherche des données.

Les deuxième et troisième octets peuvent contenir des données à manipuler ou des adresses qui indiquent l'emplacement des données. Les données manipulées sont appelées opérandes.

Format de commande à un octet comme illustré dans 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 désignation mnémonique. La mnémonique (du grec mnémonique - l'art de la mémorisation) facilite la mémorisation des commandes en fonction de leur objectif fonctionnel.

Avant son 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 situé 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 être situés 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 résider dans des périphériques d'E / S (cas le plus rare). L'emplacement des opérandes est déterminé par le code de commande. Il existe différentes méthodes par lesquelles le code d'instruction peut déterminer où obtenir 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, il existe les méthodes d'adressage suivantes:

Immédiat;

Inscrit;

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 le deuxième ou dans les deuxième et troisième octets de la commande, avec l'octet de données le moins significatif dans le deuxième octet de la commande , et le plus significatif dans les commandes du troisième octet.

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

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

Indirect L'adressage (implicite) suppose que dans le registre interne du MP il n'y a 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 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 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 (dont 244 modifications).

Les groupes de commandes suivants sont distingués:

Transmission de données;

Arithmétique;

Casse-tête;

Commandes de transition;

Commandes d'E / S, contrôle et travail avec la pile.


Symboles et abréviations utilisés dans les descriptions de commandes et la programmation

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)
BYTE 2 Octet de deuxième commande
BYTE 3 Troisième octet de commande
R, R1, R2 Un des registres: A, B, C, D, E, H, L
RP L'une des paires de registres: B - définit la paire BC; D - définit la paire DE; H - définit la paire HL
RH Premier registre d'une paire
RL Deuxième registre de la paire
Λ Multiplication logique
V Ajout logique
Ajout mod deux
M Cellule de mémoire dont l'adresse définit le contenu de la paire de registres HL, c'est-à-dire M \u003d (HL)
Partagez ceci