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

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

Plan:

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. Pour utilisation pratique plus confortable 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ération 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) Tous des lettres: 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 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 sont:

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 entourés de caractères simples ou double citation;

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,d,e,F ou UN,B,C,D,E,F.

Deuxièmement, le traducteur peut avoir des difficultés à reconnaître les nombres hexadécimaux du fait qu'ils peuvent être constitués uniquement des chiffres 0...9 (par exemple, 190845) ou 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. La description syntaxique d'un 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 ) mais avec différentes méthodes d'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Échange ). 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, par exemple, le calcul de fonctions trigonométriques, de fonctions logarithmiques, ainsi que des 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 de instructions 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 donnés (l'un des opérandes est le code de masque, dans lequel les bits à effacer sont mis à zéro). L'opération OU est utilisée pour forcer les bits définis (comme l'un des opérandes, le code de masque est utilisé, dans lequel les bits qui doivent être définis sur 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 (booléen, arithmétique ou cyclique) détermine quelle sera la nouvelle valeur du bit le plus significatif (lorsqu'il est décalé vers la droite) ou du bit le moins significatif (lorsqu'il est décalé vers la gauche), et détermine également si l'ancienne valeur du bit le plus significatif bit sera stocké quelque part (lorsqu'il est décalé vers la gauche) ou le bit le moins significatif (lorsqu'il est décalé 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 commandes de saut inconditionnel provoquent un saut vers nouvelle adresse peu importe ce que. 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 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.

­ Questions de contrôle :

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. À notre époque, la science et la vie ne peuvent être imaginées sans les dernières technologies. Tout ce qui est lié à l'activité humaine ne peut se passer l'informatique. Et cela contribue à son développement élevé et à sa perfection. Même si le développement des ordinateurs personnels a commencé il n'y a pas si longtemps, mais pendant ce temps, des pas colossaux ont été franchis dans les produits logiciels et 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 l'on ne prend pas en considération le côté commercial, alors on peut 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 existe une concurrence et une demande de performances de qualité, de travail stable et répondant à toutes les exigences de notre époque. Ici, il convient également de noter l'apparition des microprocesseurs dans les années 60, qui sont venus remplacer un grand nombre de jeux de lampes. Certaines variétés de microprocesseurs sont très différentes les unes des autres. Ces microprocesseurs diffèrent les uns des autres en termes de capacité en bits et de commandes système intégrées. Les plus courants sont : Intel, IBM, Celeron, AMD, etc. Tous ces processeurs sont liés à l'architecture avancée des processeurs Intel. La diffusion des micro-ordinateurs a provoqué une refonte des attitudes envers le langage d'assemblage pour deux raisons principales. Premièrement, les programmes écrits en langage d'assemblage nécessitent beaucoup moins de mémoire et d'exécution. Deuxièmement, la connaissance du langage d'assemblage et du code machine qui en résulte donne une compréhension de l'architecture de la machine, ce qui n'est guère fourni lorsque l'on travaille dans un langage de haut niveau. Bien que la plupart des ingénieurs logiciels développent dans des langages de haut niveau tels que Pascal, C ou Delphi, qui est plus facile à écrire des programmes, le plus puissant et le plus efficace logiciel entièrement ou partiellement écrit en langage assembleur. Les langages de haut niveau ont été conçus pour éviter des caractéristiques techniques ordinateurs spécifiques. Et le langage d'assemblage, à son tour, est conçu pour les spécificités spécifiques du processeur. Par conséquent, afin d'écrire un programme en langage assembleur pour un ordinateur particulier, il faut connaître son architecture. De nos jours, la vue de la principale produit logiciel est un fichier EXE. Considérant côtés positifs ceci, 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. Ecrire des virus sur des raisons différentes. 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 objectif fonctionnel, regardons le schéma fonctionnel d'un 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 - ce sont CPU Et RAM. Et, enfin, l'ordinateur a des organes de la parole qui donnent les résultats du traitement. Ce sont aussi quelques-uns des appareils sur la droite.

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

Poursuivant l'analogie avec une personne, notons: 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 fournir travail efficace avec du matériel. Parfois, des parties critiques du programme en termes de temps d'exécution ou de consommation de mémoire sont écrites en assembleur. Par la suite, ils sont réalisés sous forme de sous-programmes et combinés avec du code dans un langage de haut niveau.

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

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

^ 16 registres personnalisés ;

16 registres système.

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

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

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

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

registres d'état et de contrôle :

Les drapeaux enregistrent les eflags/drapeaux ;

registre de pointeur de commande eip/ip.

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

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

^ Registres à usage général
Tous les registres de ce groupe permettent d'accéder à leurs parties « inférieures » (voir Fig. 3). En regardant cette figure, notez que seules les parties inférieures de 16 et 8 bits de ces registres peuvent être utilisées pour l'auto-adressage. Les 16 bits supérieurs de ces registres ne sont pas disponibles en tant qu'objets indépendants. Ceci est fait, comme nous l'avons noté ci-dessus, pour la compatibilité avec les modèles de microprocesseurs 16 bits plus récents d'Intel.

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

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

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

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

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

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

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

edi/di (registre d'index de destination) - index du destinataire (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 modèle de programme microprocesseur pour cela il existe des registres spéciaux :

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

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

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

Fig 4. Organisation de la pile : a - é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ération 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 du contournement indiqué par les flèches, car parmi les chemins, il peut y avoir ceux qui peuvent être suivis de droite à gauche. En fait, les diagrammes syntaxiques reflètent la logique du traducteur lors de l'analyse des phrases d'entrée du programme.

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

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

Chiffres de 0 à 9 ;

Signes ?, @, $, _, & ;

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

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

Les jetons sont :

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

^ Commandes du langage d'assemblage.

Les commandes d'assemblage ouvrent la possibilité 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 :

But:

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

le changement de tâche.

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

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

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

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

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

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

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

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

Code objet (quatre formats) :

Adressage direct dans un segment :

|11101000|disp-bas|diep-haut|

Adressage indirect dans un segment :

|11111111|mod010r/m|

Adressage indirect entre segments :

|11111111|mod011r/m|

Adressage direct entre segments :

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

CMP
(comparer les opérandes)

Comparaison d'opérandes

^ Aperçu de la commande :

cmp opérande1, opérande2

Objet : comparaison de deux opérandes.

Algorithme de travail :

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

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

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

Code objet (trois formats) :

Registre ou mémoire enregistrée :

|001110dw|modreg/m|

Valeur immédiate avec registre AX (AL) :

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

Valeur immédiate avec registre ou mémoire :

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

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

Opérande décrémenté de un

^ Aperçu de la commande :

déc opérande

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

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

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

Registre : |01001reg|

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

DIV
(DIVide non signé)

Section non signée

Schéma de commande :

diviseur div

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

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

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

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

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

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

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

Code objet:

|1111011w|mod110r/m|

INT
(Interrompre)

Appel d'une routine de service d'interruption

^ Aperçu de la commande :

int interruption_numéro

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

^ Algorithme de travail :

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

remettre à zéro les drapeaux if et tf ;

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

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

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

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

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

Code objet (deux formats) :

S'inscrire : |01000reg|

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

CCJ
JCXZ/JECXZ
(Sauter si condition)

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

Sauter si la condition est remplie

Sauter si CX/ECX est nul

^ Aperçu de la commande :

label jcc
étiquette jcxz
étiquette jecxz

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

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

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

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

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

si la condition cochée

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

Chaque instruction machine se compose de deux parties :

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

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

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

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

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

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

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

Exemples de lignes de code :

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

Mots clés

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

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

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

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

Équipes

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

directives

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

opérandes

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

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

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

Les opérandes peuvent être

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

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

Règles d'écriture des identifiants.

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

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

Structure du programme d'assemblage

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

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

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

RET
FIN DEBUT

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

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 modifier 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 opérateur Entrelacement de code et de données TINY NEAR MS-DOS Autorisé 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 Autorisé 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, avec tous les liens dans les segments de code considérés comme éloignés (loin) par défaut, et les liens dans le segment de données sont considérés comme 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 de 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. 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 plat. 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. 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 assembleur Un traducteur est un programme ou moyens techniques A qui convertit un programme 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 d'instructions machine, chaque traducteur 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. filet.

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

Src="https://present5.com/presentation/-29367016_63610977/image-16.jpg" alt="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="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 périphériques externes et les ressources du système d'exploitation se produit, en règle générale, à travers 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 Fonctionnalités Windows API 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é]: PRÈS. 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




Haut