Le débogueur
Le débogueur, le programme DEBUG.EXE proposé avec le système d'exploitation MS-DOS, tire ses origines de Tim Paterson. Ainsi, en 1980, Tim Paterson a commencé à travailler sur un système d'exploitation 16 bits pour la carte de bus 8086 S-100 qu'il avait conçue pour SCP (Seattle Computer Products) l'année précédente. Pour aider à faire fonctionner les QDOS (appelé 86-DOS), Tim a créé un débogueur dans une puce en ROM; Le code de cette version ROM a été publié dans le domaine public. Plus tard, Tim a adapté le code pour s'exécuter en tant que programme .COM sous QDOS, et a également ajouté la possibilité de démonter le code machine 8086. En attendant, Microsoft avait été occupé à acheter les droits de vendre des QDOS de Tim à IBM pour leur projet PC «secret». Tim a ensuite été embauché par Microsoft comme l'auteur principal de leur premier système d'exploitation. Lorsqu'il a terminé son travail sur le Personal Computer DOS 1.00 d'IBM en 1981, son utilitaire DEBUG.COM a été inclus avec lui. Toutes les fonctionnalités que Tim mettent dans le débogage est toujours là et peu de choses y ont été ajoutées (l'exception principale étant la commande d'assemblage; ajoutée sous DOS 2.0).
Avec la réalisation du DOS 2.0, DEBUG a gagné la possibilité d'assembler les instructions directement dans le code machine (la commande A). Il s'agit de l'une des commandes les plus importantes pour bon nombre de ses utilisateurs. Bien que manquant d'une grande partie des fonctionnalités d'un assembleur autonome, par exemple, tous les sauts doivent être aux adresses hexadécimales (aucune étiquette ne peut être utilisée), de nombreux programmes .COM utiles ont été assemblés avec cette commande. A partir de la version du DOS 3.0, la commande P (procédé à partir d'une adresse optionnelle) a été ajoutée, afin que le débogage puisse rapidement exécuter des sous-programmes; dans le même temps, il est devenu possible de tenter de passer à travers des interruptions avec la commande T (trace). Lorsque DOS a ajouter des fonctions EMS (mémoire étendue) disponibles sous DOS 4.0, les quatre commandes XA, XD, XM et XS ont également été ajoutées à Debug. Par la suite, le seul changement notable de débogage a été l'ajout de la commande d'aide (tapé un '?' à l'intérieur de débogage) sous DOS 5.0; quand toutes les commandes DOS ont finalement obtenu le /? commutateur de ligne de commande.
Les premiers pas
Pour lancer Le débogueur DEBUG.EXE, vous devez tapez la commande suivante dans l'interpréteur de commande du système d'exploitation :
debug |
Au bout de quelques instant, il affiche un prompt «-». Vous entrez alors dans un interpréteur de commande, sauf que les commandes que vous entrez sont maintenant ceux reconnus par DEBUG. Vous pouvez vérifiez que vous êtes bien dedans en tapez la commande d'aide :
? |
Vous aurez donc un résultat ressemblant à ceci :
Les limites du débogueur
Le programme DEBUG a été initialement conçu pour fonctionner avec des programmes .COM ayant une taille maximale de seulement 65 280 octets [(64 x 1024) - 256] ou moins; Combien moins dépendait du nombre maximal d'octets que le programme devait placer sur la pile en même temps. La soustraction de 256 octets est nécessaire car le débogage utilise souvent la zone du déplacement de 00 à FF Hex pour certaines données internes (PSP) telles que le nom du fichier chargé. N'oubliez pas que les vrais programmes .COM par définition sont censés s'intégrer dans un seul segment de mémoire (seulement 64 kib).
Même lors de l'exécution de DEBUG sous les anciennes versions du système d'exploitation Windows, car il s'agit toujours d'une ancienne application DOS en 16 bits, vous ne pouvez ouvrir que des fichiers dont les noms ont été enregistrés dans la convention 8.3 DOS; c'est-à-dire jusqu'à 11 caractères au total, en utilisant pas plus de 8 caractères DOS pour le nom et 3 pour l'extension.
Dès le DOS 1.10, le programme DEBUG a pu charger des fichiers supérieurs à 64 kib. Fondamentalement, la taille d'un fichier que débogage peut utiliser en toute sécurité sans erreur dépend de la quantité de mémoire disponible et de la façon dont le système d'exploitation gère la gestion de la mémoire.
Lorsque le débogage commence sans paramètres de ligne de commande, il effectue les opérations suivantes :
- Alloue les 64 kib du premier segment de mémoire libre.
- Les registres du segment, CS, DS, ES et SS sont tous définis sur la valeur de l'emplacement de ce segment de 64 kib (CS = DS = ES = SS = emplacement du segment).
- Le pointeur d'instruction (IP) est défini sur CS:0100 et le pointeur de pile (SP) est défini sur SS:FFEE (sous DOS 3.0 ou supérieur).
- Les registres, AX, BX, CX, DX, BP, SI et DI sont effacés à zéro avec les bits de drapeau dans le registre des drapeaux; À une exception: le drapeau d'interruption est défini pour activer les interruptions.
Lorsque le débogage commence par un nom de fichier (autre qu'un .exe), il effectue les opérations suivantes :
- Alloue au moins 64 kib du premier segment de mémoire libre pour déboguer les programmes ou examiner les fichiers spécifiés sur la ligne de commande. Depuis DOS version 1.10, Debug a la possibilité de charger (et d'enregistrer) des fichiers supérieurs à 64 kib. La taille d'un fichier qu'il peut gérer dépend à la fois du système d'exploitation et de la mémoire disponible. Mais avant d'envisager d'utiliser DEBUG pour enregistrer un grand fichier que vous souhaitez modifier, vous devez savoir que la quantité de mémoire qu'il peut utiliser est limitée à ce qui est disponible dans la mémoire conventionnelle uniquement ! Et n'oubliez pas que ce n'est pas parce que votre système peut déboguer un certain fichier.
- Les registres du segment, CS, DS, ES et SS sont tous définis sur la valeur de l'emplacement du segment des 64 premiers kib (cs = ds = es = ss = emplacement du segment); Pour un fichier supérieur à 64KIB, vous devrez définir différentes valeurs de segment pour accéder à tous les octets chargés en mémoire au-delà du premier KIB 64.
- Le pointeur d'instruction (IP) est défini sur CS:0100 et le pointeur de pile (SP) est défini sur SS:FFFE (version 3.0+).
- La plupart des registres suivent le même modèle que ci-dessus, à l'exception des registres CX et parfois BX: la taille du fichier sera placée dans la combinaison linéaire des registres BX et CX; Pour les fichiers inférieurs à 64 kib - 256 octets, seul CX est utilisé. Exemple: Si vous pouvez charger un fichier de 360 247 octets, alors BX = 0005 et CX = 7F37 (57F37 Hex = 360 247). Si vous chargez un fichier de 65 536 octets exactement à partir d'une invite, ces registres seront: BX = 0001, CX = 0000. Mais en raison du déplacement automatique de la charge de 100h, les 256 derniers octets du fichier auront été chargés au début du prochain segment KIB.
Le segment attribué au débogage dépend de la quantité de mémoire utilisée, et non de la mémoire totale disponible. Ainsi, la même machine DOS, qu'elle ait 16 ou même 4096 MIB de mémoire, chargera généralement le débogage dans le même segment; À moins qu'un programme TSR (terminate and stay resident) utilise cette mémoire, ou que la mémoire ne soit pas correctement traitée avant d'exécuter le débogage.
Utilisation de DEBUG avec des fichiers .EXE
Toute version de DEBUG de DOS 2.0 ou supérieur utilise la fonction EXEC (Interruption 21h,Fonction 4Bh) du système d'exploitation, ce qui signifie qu'il est possible pour vous d'effectuer une quantité limitée de débogage sur un programme «.EXE». Cependant, le débogage ne peut jamais être utilisé pour enregistrer un «.EXE» ou un fichier .HEX sur disque, car ces deux types de fichiers contiennent des données supplémentaires que DEBUG n'a jamais été programmée pour créer après que EXEC a supprimé ces données ! Il est tout à fait possible de modifier l'extension d'un fichier «.EXE», par exemple en .BIN, donc DEBUG peut être utilisé pour modifier un tel fichier, puis le modifier par une extension «.EXE» par la suite. Normalement, nous vous recommandons d'utiliser un éditeur hexadécimal à la place, mais nous souhaitons souligner que le débogage pourrait être utilisé avec des fichiers et des scripts de lots pour effectuer de telles modifications automatiquement; prendre la place d'un programme de correctif.
Les registres du microprocesseur 8086
Premièrement, une revue rapide de la façon dont les nombres binaires et hexadécimaux sont liés : lorsque ceux et les zéros de quatre bits binaires sont regroupés (de 0000 à 1111; souvent appelés gribouillis), ils peuvent être représentés par un seul chiffre hexadécimal (à partir de 0 à f); Les deux sont utilisés pour compter de 0 à 15 en décimal. Huit bits binaires (permettant toute valeur décimale de 0 à 255) sont représentés par deux chiffres hexadécimaux; Par exemple, le numéro binaire 10101010 est égal à AA en hexadécimal. Les numéros hexadécimaux à deux chiffres (ou nombres binaires 8 bits) sont appelés octets. Peu importe le nombre de chiffres d'un nombre en binaire ou hexadécimal, vous pouvez basculer entre les deux en regroupant et en convertissant tous les quatre bits binaires en un chiffre hexadécimal ou vice versa. L'équivalent hexadécimal d'un binaire 12 bits doit avoir 3 chiffres (par exemple, 10101011100 = ABC en Hexadécimal), et le plus grand nombre décimal pouvant être représenté par seize bits binaires (65 535) est équivalent à FFFF en hexadécimal.
Les quatre registres principaux (16 bits) d'un processeur 8086 sont appelés : l'accumulateur (AX), la base (BX), le nombre (CX) et les registres de données (DX). Chacun de ces registres a une moitié élevée (H) et faible (L) 8 bits pouvant entreposer un octet hexadécimal (1 octet = 8 bits binaires). Chacune de ces moitiés hautes et basses est accessible séparément par code de programme :
Les autres registres 16 bits (deux octets) du microprocesseur 8086 sont :
Le microprocesseur 8086 utilise une méthode de segment:déplacement chaque fois qu'il a besoin d'accéder aux emplacements de mémoire ou de passer d'un segment de 64 Ko à un autre. Il le fait en combinant deux registres 16 bits pour former un segment 20 bits : valeur de déplacement (ce qui signifie qu'il peut accéder à plus de 1 Mo de mémoire de cette façon). Pour certains types de tâches, les registres sont souvent regroupés de la même manière, mais le programmeur doit toujours s'assurer que le microprocesseur les utilisera comme prévu. Voici quelques tâches étant fixées par le microprocesseur lui-même :
Deux autres ensembles étant souvent utilisés ensemble dans les opérations de chaîne de caractères sont :
Le registre des drapeaux
Si vous souhaitez vraiment utiliser Debug dans le registre pour chaque instruction du programme que vous examinez. (Assurez-vous d'étudier le tableau final ci-dessous si vous lisez des manuels qui discutent du nouveau registre des drapeaux de 16 bits. De plus récents débogueurs 32 bits, tels que Turbo Debugger de Borland, affichent les huit drapeaux que Debug, mais utilisez une abréviation Pour le nom du drapeau et montrez simplement s'il s'agit d'un 0 ou 1 bit.)
Il s'agit d'un registre 8 bits contenant des données 1 bits pour chacun des huit drapeaux devant être interprétés comme suit :
Abréviation du manuel des noms de drapeau | of | df | if | sf | zf | af | pf | cf |
---|---|---|---|---|---|---|---|---|
Si les drapeaux étaient tous définis (1), ils ressembleraient à ceci : | OV | DN | EI | NG | ZR | AC | PE | CY |
Si les drapeaux étaient tous effacés (0), ils ressembleraient à ceci : | NV | UP | DI | PL | NZ | NA | PO | NC |
Voici la signification des abréviations (ce sont les mêmes que des logiciels comme CodeView) :
Drapeaux | Abréviation | Fixé (Bit vaut 1) | Effacé (Bit vaut 0) |
---|---|---|---|
Débordement | of | OV (OVerflow) | NV (No oVerflow) |
Direction | df | DN (Down - Decrement) | UP (Up - Increment) |
Interruption | if | EI (Enabled Interrupt) | DI (Disabled Interrupt) |
Signe | sf | NG (negative) | PL (positive) |
Zéro | zf | ZR (Zero) | NZ (Not zero) |
Retenue auxiliaire | af | AC (Auxiliary Carry) | NA (No AC) |
Parité | pf | PE (Parity Even) | PO (Parity Odd) |
Retenue | cf | CY (CarrY) | NC (No Carry) |
Comment les drapeaux sont définis dans les registres
Le mot fixé signifie qu'un bit est défini sur 1, tandis que les mots réinitialisés ou effacés signifient un bit est défini sur 0.
Le drapeau de direction (bit 10; Fixé = Down, 0 = Up) et interruption (bit 9; set = activé, 0 = désactivé) sont quelque peu évidents. Cependant, les drapeaux suivants nécessitent une explication détaillée :
- Le drapeau de débordement (of; bit 11) est défini lorsqu'une opération se traduit par un débordement signé; qui se produit lorsqu'il y a une retenue dans mais pas hors du bit d'ordre élevé, ou vice-versa (sur mais pas dedans). Ainsi, pour une opération de 8, 16 ou 32 bits, ne sera définie que s'il y avait un débordement au bit 7, 15 ou 31 pour l'opération respective (n'oubliez pas, le nombre de bits commence avec zéro).
- Le drap;eau de signe (SF; bit 7) n'est défini que lorsque le bit d'ordre élevé est défini. Ainsi, pour les opérations de 8, 16 ou 32 bits, SF ne sera défini que s'il y a un 1 dans le bit 7, 15 ou 31; Ainsi, il a le même état que le bit d'ordre élevé du résultat.
- Le drapeau zéro (ZF; bit 6) n'est défini que lorsque tous les bits du résultat sont nuls; Sinon, c'est réinitialisé.
- Le drapeau auxiliaire (AF; bit 4) n'est défini que lorsque le bit 3 (quelle que soit la taille de l'opérande) du résultat en a une réalisation pendant l'addition, ou une retenue pendant la soustraction. La FA est généralement utilisée avec des quantités BCD emballées, mais elle sera toujours définie chaque fois que les conditions appropriées seront rencontrées.
- Le drapeau de parité (pf; bit 2) n'est défini que lorsque les 8 bits de faible ordre (quelle que soit la taille de l'opérande) ont un nombre uniforme de bits "1" (même la parité); C'est réinitialisé quand ils ont une parité étrange.
- Le drapeau de retenue (cf; bit 0) est défini lorsqu'une opération entraîne une retenue (pendant l'addition), ou une retenue (pendant la soustraction) du bit d'ordre élevé. Ainsi, pour les opérations de 8, 16 ou 32 bits, CF ne sera réglé que s'il y avait un report au bit 7, 15 ou 31 pour l'opération respective.