Maison / Spam / Résumé : Plan : Préface. Langage d'assemblage et structure d'instructions. La structure du fichier exe (analyse sémantique). Commandes en langage assembleur (Cours) Commandes de tableau en langage assembleur

Résumé : Plan : Préface. Langage d'assemblage et structure d'instructions. La structure du fichier exe (analyse sémantique). Commandes en langage assembleur (Cours) Commandes de tableau en langage assembleur

Structure des instructions du langage d'assemblage La programmation au niveau des instructions machine est le niveau minimum auquel la programmation informatique est possible. Le système d'instructions de la machine doit être suffisant pour mettre en œuvre les actions requises en donnant des instructions au matériel de la machine. Chaque instruction machine se compose de deux parties : une partie opératoire qui définit « quoi faire » et un opérande qui définit les objets de traitement, c'est-à-dire « quoi faire ». L'instruction machine du microprocesseur, écrite en langage assembleur, est une ligne unique, ayant la forme suivante : étiquette instruction/instruction(s) opérande(s) ; commentaires L'étiquette, la commande/directive et l'opérande sont séparés par au moins un espace ou un caractère de tabulation. Les opérandes d'instruction sont séparés par des virgules.

Structure d'une instruction en langage assembleur Une instruction en langage assembleur indique au compilateur quelle action le microprocesseur doit effectuer. Les directives d'assemblage sont des paramètres spécifiés dans le texte du programme qui affectent le processus d'assemblage ou les propriétés du fichier de sortie. L'opérande spécifie la valeur initiale des données (dans le segment de données) ou les éléments sur lesquels l'instruction doit agir (dans le segment de code). Une instruction peut avoir un ou deux opérandes, ou aucun opérande. Le nombre d'opérandes est spécifié implicitement par le code d'instruction. Si la commande ou la directive doit être poursuivie sur la ligne suivante, le caractère barre oblique inverse est utilisé : "" . Par défaut, l'assembleur ne fait pas la distinction entre les lettres majuscules et minuscules dans les commandes et les directives. Exemples de directives et de commandes Count db 1 ; Nom, directive, un opérande mov eax, 0 ; Commande, deux opérandes

Les identificateurs sont des séquences de caractères valides utilisés pour désigner des noms de variables et des noms d'étiquettes. L'identifiant peut être composé d'un ou plusieurs des 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 de l'étiquette. Les noms d'assembleur réservés (directives, opérateurs, noms de commande) ne peuvent pas être utilisés comme identificateurs. Le premier caractère de l'identifiant doit être une lettre ou un caractère spécial. La longueur maximale de l'identifiant est de 255 caractères, mais le traducteur accepte les 32 premiers caractères et ignore le reste. Toutes les étiquettes écrites sur une ligne qui ne contient pas de directive assembleur doivent se terminer par deux points ":". L'étiquette, la commande (directive) et l'opérande ne doivent pas commencer à une position particulière dans la chaîne. Il est recommandé de les écrire dans une colonne pour une plus grande lisibilité du programme.

Étiquettes Toutes les étiquettes écrites sur une ligne qui ne contient pas de directive assembleur doivent se terminer par deux-points ":". L'étiquette, la commande (directive) et l'opérande ne doivent pas commencer à une position particulière dans la chaîne. Il est recommandé de les écrire dans une colonne pour une plus grande lisibilité du programme.

Commentaires 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. Les commentaires commencent sur n'importe quelle ligne d'un module source par un point-virgule (;). Tous les caractères à droite de " ; ' à la fin de la ligne sont des commentaires. Le commentaire peut contenir n'importe quel caractère imprimable, y compris "l'espace". Le commentaire peut s'étendre sur toute la ligne ou suivre la commande sur la même ligne.

Structure d'un programme en langage assembleur Un programme en langage assembleur peut être composé de plusieurs parties, appelées modules, chacune pouvant 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 des segments de programme, de données et de pile déclarés avec les directives appropriées.

Modèles de mémoire Avant de déclarer des segments, vous devez spécifier le modèle de mémoire à l'aide d'une directive. MODEL modificateur memory_model, calling_convention, OS_type, stack_parameter Modèles de mémoire en langage assembleur de base : Modèle de mémoire Adressage de code Adressage de données Système d'exploitation Entrelacement de code et de données TINY NEAR MS-DOS Valid SMALL NEAR MS-DOS, Windows Non MEDIUM FAR NEAR MS-DOS, Windows Non COMPACT NEAR FAR MS-DOS, Windows Non LARGE FAR MS-DOS, Windows Non HUGE FAR MS-DOS, Windows Non NEAR Windows 2000, Windows XP, Windows Valid FLAT NEAR NT,

Modèles de mémoire Le petit modèle ne fonctionne que dans les applications MS-DOS 16 bits. Dans ce modèle, toutes les données et le code résident dans un seul segment physique. La taille du fichier programme dans ce cas ne dépasse pas 64 Ko. Le petit modèle prend en charge un segment de code et un segment de données. Les données et le code lors de l'utilisation de ce modèle sont traités comme proches (near). Le modèle moyen prend en charge plusieurs segments de code et un segment de données, tous les liens dans les segments de code étant considérés comme éloignés par défaut, et les liens dans le segment de données étant proches (proche). Le modèle compact prend en charge plusieurs segments de données qui utilisent l'adressage des données distantes (far) et un segment de code qui utilise l'adressage des données proches (near). Le grand modèle prend en charge plusieurs segments de code et plusieurs segments de données. Par défaut, toutes les références de code et de données sont considérées loin. Le modèle énorme est presque équivalent au modèle à grande mémoire.

Modèles de mémoire Le modèle plat suppose une configuration de programme non segmentée et n'est utilisé que sur les systèmes d'exploitation 32 bits. Ce modèle est similaire au petit modèle en ce sens que les données et le code résident dans le même segment 32 bits. Développer un programme pour le modèle plat avant la directive. appartement modèle doit placer l'une des directives : . 386, . 486, . 586 ou. 686. Le choix de la directive de sélection du processeur détermine l'ensemble des commandes disponibles lors de l'écriture des programmes. La lettre p après la directive de sélection du processeur signifie un mode de fonctionnement protégé. L'adressage des données et du code est proche, toutes les adresses et tous les pointeurs étant de 32 bits.

modèles de mémoire. MODEL modifier memory_model, calling_convention, OS_type, stack_parameter Le paramètre modifier est utilisé pour définir les types de segment et peut prendre les valeurs suivantes : use 16 (les segments du modèle sélectionné sont utilisés en 16 bits) use 32 (les segments du modèle sélectionné sont utilisés comme 32 bits). Le paramètre calling_convention est utilisé pour déterminer comment les paramètres sont passés lors de l'appel d'une procédure à partir d'autres langages, y compris les langages haut niveau(C++, Pascal). Le paramètre peut prendre les valeurs suivantes : C, BASIC, FORTRAN, PASCAL, SYSCALL, STDCALL.

modèles de mémoire. MODÈLE modificateur memory_model, calling_convention, OS_type, stack_parameter Le paramètre OS_type est OS_DOS par défaut, et sur ce moment c'est la seule valeur prise en charge pour ce paramètre. Le paramètre stack_param est défini sur : NEARSTACK (le registre SS est égal à DS, les régions de données et de pile sont situées dans le même segment physique) FARSTACK (le registre SS n'est pas égal à DS, les régions de données et de pile sont situées dans des segments physiques différents). La valeur par défaut est NEARSTACK.

Un exemple de programme "ne rien faire". 686 P. MODÈLE PLAT, STDCALL. LES DONNÉES. CODE DEBUT : RET FIN DEBUT RET - commande du microprocesseur. Il assure la fin correcte du programme. Le reste du programme est lié au fonctionnement du traducteur. . 686 P - 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. . MODEL FLAT, stdcall - modèle de mémoire plate. Ce modèle de mémoire est utilisé dans le système d'exploitation Windows. stdcall est la convention d'appel de procédure à utiliser.

Un exemple de programme "ne rien faire". 686 P. MODÈLE PLAT, STDCALL. LES DONNÉES. CODE DEBUT : RET FIN DEBUT . DATA - segment de programme contenant des données. Ce programme n'utilise pas la pile, donc segment. STACK est manquant. . CODE - un segment du programme contenant le code. DÉMARRER - étiquette. END START - la fin du programme et un message au compilateur indiquant que le programme doit être démarré à partir de l'étiquette START. Chaque programme doit contenir une directive END qui marque la fin du code source du programme. Toutes les lignes qui suivent la directive END sont ignorées. 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.

Traducteurs en langage d'assemblage Un traducteur est un programme ou un matériel qui convertit un programme présenté dans l'un des langages de programmation en un programme dans le langage cible, appelé code objet. En plus de prendre en charge les mnémoniques des instructions machine, chaque compilateur possède son propre ensemble de directives et de macros, souvent incompatibles avec quoi que ce soit d'autre. Les principaux types de traducteurs de langage d'assemblage sont : MASM (Microsoft Assembler), TASM (Borland Turbo Assembler), FASM (Flat Assembler) - un assembleur multi-passes librement distribué écrit par Tomasz Gryshtar (polonais), NASM (Netwide Assembler) - un L'assembleur libre pour l'architecture Intel x 86 a été créé par Simon Tatham avec Julian Hall et est actuellement développé par une petite équipe de développement chez Source. Forger. rapporter.

Src="https://present5.com/presentation/-29367016_63610977/image-15.jpg" alt="(!LANG:Traduction du programme dans Microsoft Visual Studio 2005 1) Créez un projet en sélectionnant Fichier->Nouveau->Projet menus et"> Трансляция программы в Microsoft Visual Studio 2005 1) Создать проект, выбрав меню File->New->Project и указав имя проекта (hello. prj) и тип проекта: Win 32 Project. В !} options additionelles assistant de projet pour spécifier "Projet vide".

Src="https://present5.com/presentation/-29367016_63610977/image-16.jpg" alt="(!LANG:Program translation in Microsoft Visual Studio 2005 2) Dans l'arborescence du projet (View->Solution Explorer) ajouter"> Трансляция программы в Microsoft Visual Studio 2005 2) В дереве проекта (View->Solution Explorer) добавить файл, в котором будет содержаться текст программы: Source. Files->Add->New. Item.!}

Traduction du programme dans Microsoft Visual Studio 2005 3) Sélectionnez le type de fichier Code C++, mais spécifiez le nom avec l'extension. asm :

Traduction du programme dans Microsoft Visual Studio 2005 5) Définir les options du compilateur. Sélectionnez sur le bouton droit dans le menu du fichier de projet Custom Build Rules…

Traduction du programme dans Microsoft Visual Studio 2005 et dans la fenêtre qui apparaît, sélectionnez Microsoft Macro Assembler.

Traduction du programme en Microsoft Visual Studio 2005 Vérifier par le bouton droit dans le fichier bonjour. asm de l'arborescence du projet dans le menu Propriétés et définissez Général->Outil : Microsoft Macro Assembler.

Src="https://present5.com/presentation/-29367016_63610977/image-22.jpg" alt="(!LANG:Program translation in Microsoft Visual Studio 2005 6) Compilez le fichier en sélectionnant Build->Build hello.prj ."> Трансляция программы в Microsoft Visual Studio 2005 6) Откомпилировать файл, выбрав Build->Build hello. prj. 7) Запустить программу, нажав F 5 или выбрав меню Debug->Start Debugging.!}

Programmation sous OS Windows La programmation sous OS Windows repose sur l'utilisation de fonctions API (Application Program Interface, c'est-à-dire l'interface d'application logicielle). Leur nombre atteint 2000. Le programme pour Windows se compose en grande partie de tels appels. Toutes les interactions avec les périphériques externes et les ressources du système d'exploitation se produisent, en règle générale, par le biais de ces fonctions. salle d'opération Système Windows utilise un modèle de mémoire plat. L'adresse de n'importe quel emplacement de mémoire sera déterminée par le contenu d'un registre de 32 bits. Il existe 3 types de structures de programme pour Windows : boîte de dialogue (la fenêtre principale est une boîte de dialogue), structure console ou sans fenêtre, structure classique (fenêtre, cadre).

Appel des fonctions API Windows Dans le fichier d'aide, toute fonction API est représentée par le type nom_fonction (FA 1, FA 2, FA 3) Type – type de valeur de retour ; FAX – liste des arguments formels dans leur ordre. Par exemple, int Message. Boîte (HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Type); Cette fonction affiche une fenêtre avec un message et un ou plusieurs boutons de sortie. Signification des paramètres : h. Wnd - handle de la fenêtre dans laquelle la fenêtre de message apparaîtra, lp. Texte - le texte qui apparaîtra dans la fenêtre, lp. Légende - texte dans le titre de la fenêtre, u. Type - type de fenêtre, en particulier, vous pouvez spécifier le nombre de boutons de sortie.

Appel des fonctions de l'API Windows dans Message. Boîte (HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Type); Presque tous les paramètres de la fonction API sont en fait des entiers 32 bits : HWND est un entier 32 bits, LPCTSTR est un pointeur de chaîne 32 bits, UINT est un entier 32 bits. Le suffixe "A" est souvent ajouté au nom des fonctions pour accéder aux versions plus récentes des fonctions.

Appel des fonctions de l'API Windows dans Message. Boîte (HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Type); Lorsque vous utilisez MASM, vous devez ajouter @N N à la fin du nom - le nombre d'octets que les arguments passés occupent sur la pile. Pour les fonctions API Win 32, ce nombre peut être défini comme le nombre d'arguments n fois 4 (octets dans chaque argument) : N=4*n. Pour appeler une fonction, l'instruction CALL de l'assembleur est utilisée. Dans ce cas, tous les arguments de la fonction lui sont passés via la pile (commande PUSH). Sens de passage des arguments : DE GAUCHE À DROITE - DE BAS EN HAUT. L'argument u sera d'abord poussé sur la pile. taper. L'appel de la fonction spécifiée ressemblera à ceci : CALL Message. boîte. [courriel protégé]

Appel des fonctions de l'API Windows dans Message. Boîte (HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Type); Le résultat de l'exécution de toute fonction API est généralement un nombre entier, qui est renvoyé dans le registre EAX. La directive OFFSET est un "décalage de segment" ou, en termes de langage de haut niveau, un "pointeur" vers le début d'une chaîne. La directive EQU, comme #define en C, définit une constante. La directive EXTERN indique au compilateur qu'une fonction ou un identifiant est externe au module.

Un exemple du programme "Bonjour tout le monde!" . 686 P. MODÈLE PLAT, STDCALL. PILE 4096. DATA MB_OK EQU 0 STR 1 DB "Mon premier programme", 0 STR 2 DB "Bonjour à tous !", 0 HW DD ? Message EXTERNE. boîte. [courriel protégé]: À PROXIMITÉ. CODE START : APPUYEZ SUR MB_OK APPUYEZ SUR OFFSET STR 1 APPUYEZ SUR OFFSET STR 2 APPUYEZ Message APPEL HW. boîte. [courriel protégé] RET FIN DEBUT

La directive INVOKE Le traducteur de langage MASM permet également de simplifier l'appel de fonction à l'aide d'un outil macro - la directive INVOKE : fonction INVOKE, paramètre1, paramètre2, ... Il n'est pas nécessaire d'ajouter @16 à l'appel de fonction ; les paramètres sont écrits exactement dans l'ordre où ils sont donnés dans la description de la fonction. les macros de traduction poussent les paramètres sur la pile. pour utiliser la directive INVOKE, vous devez avoir une description du prototype de la fonction utilisant la directive PROTO sous la forme : Message. boîte. UN PROTO : DWORD, : DWORD

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 députés. 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 de registres, des paires BC, DE, HL sont formées 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, 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 étapes simples, telles que les opérations arithmétiques et logiques élémentaires, le transfert de données, la comparaison de deux valeurs, etc. Le nombre de commandes MP KR580VM80 - 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)

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 de l'assembleur, les codes mnémoniques de 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, un opérande à deux chiffres est utilisé, 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 - unité 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é.

Sujet 1.4 Mnémoniques assembleur. Structure et formats des commandes. Types d'adressage. Jeu d'instructions du microprocesseur

Planifier:

1 Langage d'assemblage. Concepts de base

2 Symboles du langage d'assemblage

3 Types d'instructions assembleur

4 Directives de montage

5 Jeu d'instructions du processeur

1 jelangage d'assemblage. Concepts de base

langage d'assemblageest 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.

Un programme en langage assembleur est un ensemble de blocs de mémoire appelés tranches 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 :

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

2) macro -les phrases du texte de l'émission, qui sont formalisées d'une certaine manière, sont remplacées par d'autres phrases lors de la diffusion ;

3) directives,qui sont des instructions au traducteur assembleur pour effectuer certaines actions. Les directives n'ont pas d'équivalent dans la représentation machine ;

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

­ Structure du programme d'assemblage. syntaxe assembleur.

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 comme celui-ci - diagrammes de syntaxe et formes étendues de Backus-Naur. Plus pratique pour une utilisation pratique diagrammes de syntaxe. Par exemple, la syntaxe des instructions en langage assembleur peut être décrite à l'aide des diagrammes de syntaxe illustrés dans les figures 10, 11, 12 suivantes.

Figure 10 - Format de phrase d'assemblage


­ Figure 11 - Format des directives

­ Figure 12 - Format des commandes et des macros

Sur ces dessins :

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

­ Nom -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 ;

­ code d'opération (COP) et directive - il s'agit de symboles mnémoniques pour l'instruction machine, l'instruction de macro ou la directive de compilateur correspondante ;

­ opérandes -parties d'une commande, d'une macro ou d'une directive assembleur, désignant les objets sur lesquels des actions 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.

Aide des diagrammes de syntaxe trouvez puis parcourez 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.

­ 2 Symboles du langage d'assemblage

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

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

2) numéros de 0 avant de 9 ;

3) signes ? , @ , $ , _ , & ;

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

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

jetons sommes:

1) identifiants - séquences de caractères valides utilisées 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 ;

2) chaînes de caractères - séquences de caractères entre guillemets simples ou doubles ;

3) entiers dans l'un des systèmes de numération suivants : binaire, décimal, hexadécimal. L'identification des nombres lors de leur écriture dans les programmes assembleur s'effectue selon certaines règles:

4) les nombres décimaux ne nécessitent aucun symbole supplémentaire pour leur identification, par exemple 25 ou 139. Pour l'identification dans le code source du programme nombres binaires il faut, après avoir écrit les zéros et les uns inclus dans leur composition, mettre le latin « b”, par exemple 10010101 b.

5) les nombres hexadécimaux ont plus de conventions dans leur notation :

Premièrement, ils sont composés de nombres. 0...9 , minuscules et majuscules de l'alphabet latin un,b, c,,e,F ou UN,B,C,,E,F.

Deuxièmement, le traducteur peut avoir des difficultés à reconnaître les nombres hexadécimaux du fait qu'ils peuvent être composés à la fois des chiffres 0 ... 9 (par exemple, 190845) et commencer par une lettre de l'alphabet latin (par exemple, ef15). Afin "d'expliquer" au traducteur que le lexème donné n'est pas un nombre décimal ou un identifiant, le programmeur doit spécialement allouer le nombre hexadécimal. Pour ce faire, à la fin de la séquence de chiffres hexadécimaux qui composent le nombre hexadécimal, écrivez la lettre latine " h". C'est un pré-requis. Si un nombre hexadécimal commence par une lettre, il est précédé d'un zéro non significatif : 0 ef15 h.

Presque chaque phrase contient une description de l'objet sur lequel ou à l'aide duquel une action est effectuée. Ces objets sont appelés opérandes. Ils peuvent être définis comme ceci : opérandes- ce sont des objets (certaines valeurs, registres ou cellules de mémoire) qui sont affectés par des instructions ou des directives, ou ce sont des objets qui définissent ou affinent l'action d'instructions ou de directives.

Il est possible d'effectuer la classification d'opérandes suivante :

­ opérandes constants ou immédiats ;

­ opérandes d'adresse ;

­ opérandes déplacés ;

compteur d'adresses ;

­ enregistrer l'opérande ;

­ opérandes de base et d'index ;

­ opérandes structurels ;

enregistrements.

Les opérandes sont des composants élémentaires qui font partie de l'instruction machine, désignant les objets sur lesquels l'opération est effectuée. Dans un cas plus général, les opérandes peuvent être inclus comme composants dans des formations plus complexes appelées expressions.

Expressions sont des combinaisons d'opérandes et d'opérateurs considérés comme un tout. Le résultat de l'évaluation de l'expression peut être l'adresse d'une cellule de mémoire ou une valeur constante (absolue).

­ 3 Types d'instructions assembleur

Listons les types possibles instructions de l'assembleur et des règles syntaxiques pour la formation des expressions en assembleur :

­ opérateurs arithmétiques;

­ opérateurs de quarts;

­ opérateurs de comparaison ;

­ Opérateurs logiques;

­ opérateur d'index ;

­ opérateur de remplacement de type ;

­ opérateur de redéfinition de segment ;

­ opérateur de dénomination de type de structure ;

­ opérateur pour obtenir la composante segment de l'adresse de l'expression ;

­ décalage d'expression obtenir l'opérateur.

1 Directives de montage

­ Les directives de l'assembleur sont :

1) Directives de segmentation. Au cours de la discussion précédente, nous avons découvert toutes les règles de base pour écrire des instructions et des opérandes dans un programme en langage assembleur. La question de savoir comment formater correctement la séquence de commandes pour que le traducteur puisse les traiter et que le microprocesseur puisse les exécuter reste ouverte.

Lors de l'examen de l'architecture du microprocesseur, nous avons appris qu'il dispose de six registres de segments, à travers lesquels il peut fonctionner simultanément :

­ avec un segment de code ;

­ avec un segment de pile ;

­ avec un segment de données ;

­ avec trois segments de données supplémentaires.

Physiquement, un segment est une zone mémoire occupée par des commandes et (ou) des données dont les adresses sont calculées par rapport à la valeur dans le registre de segment correspondant. Description de la syntaxe segment en assembleur est la construction illustrée à la figure 13 :


­ Figure 13 - Description syntaxique du segment en assembleur

Il est important de noter que la fonctionnalité d'un segment est un peu plus large que la simple décomposition du programme en blocs de code, de données et de pile. La segmentation s'inscrit dans un mécanisme plus général lié à concept de programmation modulaire. Cela implique l'unification de la conception des modules objets créés par le compilateur, y compris ceux de différents langages de programmation. Cela vous permet de combiner des programmes écrits dans différentes langues. C'est à la mise en œuvre de diverses options pour une telle union que les opérandes de la directive SEGMENT sont destinés.

2) Liste des directives de contrôle. Les directives de contrôle des listes sont réparties dans les groupes suivants :

­ directives générales de contrôle de cotation;

­ directives de sortie pour inclure la liste des fichiers ;

­ directives de sortie pour les blocs d'assemblage conditionnels ;

­ directives de sortie pour la liste des macros ;

­ directives pour afficher des informations sur les références croisées dans la liste ;

­ directives de changement de format de liste.

2 Jeu d'instructions du processeur

Le jeu d'instructions du processeur est illustré à la figure 14.

Considérez les principaux groupes de commandes.

­ Figure 14 - Classification des instructions de montage

Les commandes sont :

1 Commandes de transfert de données. Ces instructions occupent une place très importante dans le jeu d'instructions de tout processeur. Ils remplissent les fonctions essentielles suivantes :

­ sauvegarder en mémoire le contenu des registres internes du processeur ;

­ copier le contenu d'une zone de mémoire à une autre ;

­ l'écriture sur les périphériques d'E/S et la lecture à partir des périphériques d'E/S.

Dans certains processeurs, toutes ces fonctions sont exécutées par une seule instruction MOV (pour les transferts d'octets - MOVB ) nez diverses méthodes adressage des opérandes.

Dans d'autres processeurs en plus de l'instruction MOV il existe plusieurs autres commandes pour exécuter les fonctions répertoriées. Les commandes de transfert de données incluent également les commandes d'échange d'informations (leur désignation est basée sur le motÉchanger ). Il peut être possible de prévoir l'échange d'informations entre registres internes, entre deux moitiés d'un registre (ÉCHANGER ) ou entre un registre et un emplacement mémoire.

2 commandes arithmétiques. Les instructions arithmétiques traitent les codes d'opérandes comme des codes numériques binaires ou BCD. Ces commandes peuvent être divisées en cinq groupes principaux :

­ commandes pour les opérations avec un point fixe (addition, soustraction, multiplication, division);

­ instructions en virgule flottante (addition, soustraction, multiplication, division);

­ commandes de nettoyage ;

­ commandes d'incrémentation et de décrémentation ;

­ commande de comparaison.

3 Les instructions en virgule fixe fonctionnent sur des codes dans les registres du processeur ou en mémoire comme elles le feraient avec des codes binaires normaux. Les instructions à virgule flottante (virgule) utilisent un format de représentation numérique avec un exposant et une mantisse (généralement ces nombres occupent deux emplacements de mémoire consécutifs). En moderne processeurs puissants le jeu d'instructions à virgule flottante n'est pas limité à seulement quatre opérations arithmétiques, mais contient également de nombreuses autres instructions plus complexes, telles que le calcul de fonctions trigonométriques, de fonctions logarithmiques et de fonctions complexes nécessaires au traitement du son et de l'image.

4 Les commandes d'effacement sont conçues pour écrire un code zéro dans un registre ou une cellule mémoire. Ces commandes peuvent être remplacées par des instructions de transfert à code zéro, mais les instructions claires spéciales sont généralement plus rapides que les instructions de transfert.

5 Commandes d'incrémentation (augmentation de un) et de décrémentation

(réductions par un) sont également très pratiques. Ils pourraient en principe être remplacés par des instructions d'addition ou de soustraction, mais l'incrémentation et la décrémentation sont plus rapides que l'addition et la soustraction. Ces instructions nécessitent un opérande d'entrée qui est également un opérande de sortie.

6 L'instruction de comparaison sert à comparer deux opérandes d'entrée. En fait, il calcule la différence de ces deux opérandes, mais ne forme pas l'opérande de sortie, mais modifie uniquement les bits dans le registre d'état du processeur en fonction du résultat de cette soustraction. L'instruction suivant l'instruction de comparaison (généralement une instruction de saut) analysera les bits dans le registre d'état du processeur et effectuera des actions en fonction de leurs valeurs. Certains processeurs fournissent des instructions pour comparer en chaîne deux séquences d'opérandes en mémoire.

7 Commandes logiques. Les instructions logiques effectuent des opérations logiques (au niveau du bit) sur les opérandes, c'est-à-dire qu'elles considèrent les codes d'opérande non pas comme un nombre unique, mais comme un ensemble de bits individuels. En cela, ils diffèrent des commandes arithmétiques. Les commandes logiques effectuent les opérations de base suivantes :

­ ET logique, OU logique, addition modulo 2 (XOR);

­ décalages logiques, arithmétiques et cycliques ;

­ vérification des bits et des opérandes ;

­ réglage et effacement des bits (drapeaux) du registre d'état du processeur ( PSW).

Les instructions logiques permettent le calcul bit par bit des fonctions logiques de base à partir de deux opérandes d'entrée. De plus, l'opération ET est utilisée pour forcer l'effacement des bits spécifiés (comme l'un des opérandes, cela utilise le code de masque, dans lequel les bits qui nécessitent un effacement sont mis à zéro). L'opération OU est utilisée pour forcer le réglage des bits spécifiés (comme l'un des opérandes, le code de masque est utilisé dans lequel les bits qui nécessitent un réglage à un sont égaux à un). L'opération XOR est utilisée pour inverser les bits donnés (comme l'un des opérandes, le code de masque est utilisé dans lequel les bits à inverser sont mis à un). Les instructions nécessitent deux opérandes d'entrée et forment un opérande de sortie.

8 Les commandes de décalage permettent de décaler le code de l'opérande petit à petit vers la droite (vers les bits inférieurs) ou vers la gauche (vers les bits supérieurs). Le type de décalage (logique, arithmétique ou cyclique) détermine quelle sera la nouvelle valeur du bit le plus significatif (lors du décalage vers la droite) ou du bit le moins significatif (lors du décalage vers la gauche), et détermine également si l'ancienne valeur du bit le plus significatif bit sera stocké quelque part (lors d'un décalage vers la gauche) ou le bit le moins significatif (lors d'un décalage vers la droite). Les décalages rotatifs vous permettent de décaler les bits du code d'opérande dans un cercle (dans le sens des aiguilles d'une montre lors d'un décalage vers la droite ou dans le sens inverse des aiguilles d'une montre lors d'un décalage vers la gauche). Dans ce cas, la bague de décalage peut ou non inclure le drapeau de report. Le bit d'indicateur de report (s'il est utilisé) est défini sur le bit le plus significatif pour la rotation à gauche et sur le bit le moins significatif pour la rotation à droite. En conséquence, la valeur du bit d'indicateur de report sera réécrite sur le bit le moins significatif lors d'un décalage cyclique vers la gauche et sur le bit le plus significatif lors d'un décalage cyclique vers la droite.

9 Commandes de saut. Les commandes de saut sont conçues pour organiser toutes sortes de boucles, de branchements, d'appels de sous-programmes, etc., c'est-à-dire qu'elles perturbent le déroulement séquentiel du programme. Ces instructions écrivent une nouvelle valeur dans le registre du compteur d'instructions et amènent ainsi le processeur à sauter non pas à l'instruction suivante dans l'ordre, mais à toute autre instruction dans la mémoire programme. Certaines commandes de saut vous permettent de revenir au point à partir duquel le saut a été effectué, tandis que d'autres ne le permettent pas. Si un retour est fourni, les paramètres actuels du processeur sont stockés sur la pile. Si aucun retour n'est fourni, les paramètres actuels du processeur ne sont pas enregistrés.

Les commandes de saut sans retour arrière sont divisées en deux groupes :

­ commandes de sauts inconditionnels ;

­ instructions de saut conditionnel.

Ces commandes utilisent les mots Branche (branche) et Jump (saut).

Les instructions de saut inconditionnel provoquent un saut vers une nouvelle adresse quoi qu'il arrive. Ils peuvent provoquer un saut à la valeur de décalage spécifiée (avant ou arrière) ou à l'adresse mémoire spécifiée. La valeur de décalage ou la nouvelle valeur d'adresse est spécifiée comme opérande d'entrée.

Les commandes de saut conditionnel ne provoquent pas toujours un saut, mais uniquement lorsque les conditions spécifiées sont remplies. Ces conditions sont généralement les valeurs des drapeaux dans le registre d'état du processeur ( PSW ). Autrement dit, la condition de transition est le résultat de l'opération précédente qui modifie les valeurs des drapeaux. Au total, ces conditions de saut peuvent être au nombre de 4 à 16. Quelques exemples de commandes de saut conditionnel :

­ sauter si égal à zéro ;

­ sauter si non nul ;

­ sauter s'il y a un débordement ;

­ sauter s'il n'y a pas de débordement ;

­ sauter si supérieur à zéro ;

­ sauter si inférieur ou égal à zéro.

Si la condition de transition est remplie, alors une nouvelle valeur est chargée dans le registre du compteur d'instructions. Si la condition de saut n'est pas satisfaite, le compteur d'instructions est simplement incrémenté et le processeur sélectionne et exécute l'instruction suivante en séquence.

Spécifiquement pour vérifier les conditions de branchement, on utilise une instruction de comparaison (CMP) qui précède une instruction de saut conditionnel (voire plusieurs instructions de saut conditionnel). Mais les drapeaux peuvent être définis par n'importe quelle autre commande, telle qu'une commande de transfert de données, n'importe quelle commande arithmétique ou logique. Notez que les commandes de saut elles-mêmes ne changent pas les drapeaux, ce qui vous permet simplement de mettre plusieurs commandes de saut les unes après les autres.

Les commandes d'interruption occupent une place particulière parmi les commandes de saut avec retour. Ces instructions nécessitent un numéro d'interruption (adresse vectorielle) comme opérande d'entrée.

Conclusion:

Le langage assembleur est une représentation symbolique du langage machine. Le langage d'assemblage de chaque type d'ordinateur est différent. Un programme en langage assembleur est un ensemble de blocs de mémoire appelés segments de mémoire. 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, macros, directives, lignes de commentaires.

Les caractères valides lors de l'écriture du texte des programmes sont toutes des lettres latines : A-Z,de a à z. Dans ce cas, les majuscules et les minuscules sont considérées comme équivalentes ; chiffres de 0 avant de 9 ; panneaux ? , @ , $ , _ , & ; séparateurs , . () < > { } + / * % ! " " ? = # ^ .

Les types d'instructions d'assembleur et les règles de syntaxe suivants pour la formation d'expressions d'assembleur s'appliquent. opérateurs arithmétiques, opérateurs de décalage, opérateurs de comparaison, opérateurs logiques, opérateur d'index, opérateur de redéfinition de type, opérateur de redéfinition de segment, opérateur de dénomination de type de structure, opérateur d'obtention de composant de segment d'adresse d'expression, opérateur d'obtention de décalage d'expression.

Le système de commandement est divisé en 8 groupes principaux.

­ Question test :

1 Qu'est-ce que le langage d'assemblage ?

2 Quels symboles peuvent être utilisés pour écrire des commandes en assembleur ?

3 Que sont les labels et à quoi servent-ils ?

4 Expliquer la structure des instructions de montage.

5 Énumérez 4 types d'instructions en assembleur.

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 nous ne prenons pas en considération le côté commercial, alors 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 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 y a concurrence et demande pour des performances de qualité, pour travail stable et répondant à toutes les exigences modernes. 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 de processeur avancée par 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 les particularités techniques de certains ordinateurs. 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 mon 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 d'un 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 de perception des informations du monde extérieur - il s'agit d'un clavier, d'une souris, de lecteurs de 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.

Les ordinateurs modernes, bien sûr, sont loin d'être humains. 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 besoin d'essayer de comprendre la signification de diverses combinaisons de nombres binaires, car dès les années 50, les programmeurs ont commencé à utiliser l'analogue symbolique du langage machine pour la programmation, 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 assurer un travail efficace avec le 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 de la dernière donnée stockée 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 - é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 avoir déchargé deux éléments et revenir à l'é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 original des registres sauvegardés sur la pile, nous devons exécuter les commandes pop (pop) de la pile :

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 de 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. 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. 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 instruction est utilisée pour comparer deux opérandes par soustraction, alors que les opérandes ne sont pas modifiés. 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 nombre 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 vérifiée