Question

À l'école, nous avons utilisé un programme d'amorçage pour exécuter des programmes autonomes sans système d'exploitation. Je suis en train d'étudier ce programme et lorsque le mode protégé est activé il y a un saut bien exécuté par l'assemblage directement l'opcode et opérandes sous forme de données au sein du programme. Ce fut pour l'assembleur GNU:


         /* this code immediately follows the setting of the PE flag in CR0 */

.byte   0x66, 0xEA
.long   TARGET_ADDRESS
.word   0x0010          /* descriptor #2, GDT, RPL=0 */

Tout d'abord, pourquoi voudrait-on faire (au lieu des mnémoniques d'instruction)?

J'ai regardé les manuels Intel, mais je suis encore un peu confus par le code. Plus précisément dans le volume 2A, la page 3-549, il y a une table de opcodes. L'entrée pertinente:

EA *cp* JMP ptr16:32  Inv.  Valid  Jump far, absolute, address given in
operand

La opcode réelle est évidente, mais le premier octet, 0x66, m'a confus. Se référant à la table dans le manuel Intel, le cp signifie apparemment qu'un opérande de 6 octets suivra. Et, évidemment, 6 octets suivent dans les deux lignes suivantes. 0x66 code pour un «préfixe de priorité opérande de taille. Qu'est-ce que cela a à voir avec le cp dans le tableau? Je me attendais qu'il y ait une certaine valeur hexadécimale pour le cp, mais il y a ce préfixe de priorité. Quelqu'un peut-il s'il vous plaît effacer ce pour moi?

Voici une décharge de od:

c022    **ea66    0000    0001    0010**    ba52    03f2    c030

TARGET_ADDRESS a été défini comme 0x00010000.

Je suis aussi un peu confus par l'importance des deux derniers octets. Cependant, cela semble être une autre question tout à fait. Il devient assez tard, et j'ai les yeux fixés sur le code et les manuels Intel pendant des heures, donc j'espère que je suis mon point de.

Merci pour la recherche!

Était-ce utile?

La solution

0x66 indique que le JMP (0xEA) se réfère à six octets. La valeur par défaut est 64K (référait 16 bits) en mode réel ou à 32 bits en mode protégé (si je me souviens bien). Après l'avoir augmenté, il comprend également le descripteur de segment, l'indice du segment soit dans le TDG ou LDT, ce qui signifie que ce code fait ce qu'on appelle traditionnellement un « saut en longueur »: un saut qui se croisent au-delà des segments dans la l'architecture x86. Le segment, dans ce cas, les points à la deuxième entrée sur la GDT. Si vous regardez avant dans ce programme, vous verrez probablement comment le TDG est défini en termes de segment adresse de début et la longueur (regardez dans le manuel Intel pour étudier les tables de TDG et LDT, entrée 32 bits décrivant chaque segment).

Autres conseils

Je lance dans ce un peu. Certains assembleurs ne vont sauter à une étiquette. Dans ce cas, la personne veut faire un saut absolu sur un disque spécifique Codé compensé. JMP TARGET_ADDRESS ne fonctionnera pas je suppose, donc ils ont juste comme octets pour contourner ce problème.

0x66 spécifie la taille opérande substitution de la taille actuelle du segment de code. Si l'on suppose que la taille du code actuel est de 16 bits, le nouveau pointeur d'instruction sera 32 bits, et non 16 bits. Si la taille actuelle du segment de code est 32 bits, le 0x66 sera rendu pointeur d'instruction de cible 16 bits. L'attribut courant de la taille du code dépend du sélecteur CS en cours d'utilisation et ses attributs chargés de la table TDG / LDT. En mode réel la taille du segment de code est généralement 16 bits à l'exception des cas particuliers de mode « irréel ».

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top