Mélange de code 32 bits et 16 bits avec nasm


5

Il s'agit d'une question système de bas niveau.

Je dois mélanger le code 32 bits et le code 16 bits car j'essaie de revenir en mode réel depuis le mode protégé. Comme un peu d'information de fond, mon code le fait juste après que GRUB démarre, donc je n'ai pas de système d'exploitation embêtant pour me dire ce que je peux et ne peux pas faire.

Quoi qu'il en soit, j'utilise [BITS 32] et [BITS 16] avec mon assembly pour dire nasm quels types d'opérations il devrait utiliser, mais quand je teste mon code utiliser bochs ça ressemble à certaines bochs d'opérations n'est pas l'exécution du code que j'ai écrit. On dirait que l'assembleur colle dans les extras 0x66 et 0x67 qui confond les bochs. Alors, comment puis-je obtenir nasm pour assembler avec succès le code où je mélange le code 32 bits et 16 bits dans le même fichier? Y a-t-il une sorte de tour?

0

Vous ne plaisantiez pas sur le fait que ce soit de bas niveau!

Avez-vous vérifié les opcodes/opérandes générés pour vous assurer que nasm respecte vos directives BITS correctement? Vérifiez également que les cibles de saut sont correctes - peut-être que Nasm utilise les mauvais décalages.

Si ce n'est pas un bug dans nasm, peut-être qu'il y a un bug dans les bochs. Je ne peux pas imaginer que les gens reviennent très souvent en mode 16 bits en mode 32 bits.


3

0x66 et 0x67 sont des opcodes utilisés pour indiquer que l'opcode suivant doit être interprété comme un bitness non défini par défaut. Lorsque MSNA est en mode BITS 16, les instructions qui utilisent des données 32 bits sont préfixées avec un octet 0x66, et celles qui se réfèrent à des adresses 32 bits ont un préfixe 0x67. En mode BITS 32, l'inverse est vrai: les instructions 32 bits ne nécessitent aucun préfixe, alors que les instructions utilisant des données 16 bits ont besoin d'un 0x66 et celles qui travaillent sur des adresses 16 bits ont besoin d'un 0x67. "

Ceci suggère que c'est un problème.


0

Si vous êtes en mode réel, votre taille par défaut est implicitement de 16 bits, donc vous devriez utiliser le mode BITS 16. De cette façon, si vous avez besoin d'une taille d'opérande de 32 bits, vous ajoutez le préfixe 0x66, et pour une taille d'adresse de 32 bits, vous ajoutez le préfixe 0x67.

Regardez Intel IA-32 Logiciel Guide du développeur, volume 3, chapitre 16 (MELANGE 16-BIT ET CODE 32-BIT, le numéro de chapitre pourrait changer en fonction de l'édition du livre):

Le mode d'adresse réelle, le mode virtuel-8086 et SMM sont des modes 16 bits natifs.

La directive BITS 32 ne perturbera l'assembleur que si vous l'utilisez en dehors du mode protégé ou du mode long.


6

Le problème s'est avéré être que je n'installais pas correctement mes tables de descripteur. J'avais un bit inversé donc au lieu d'aller en mode 16 bits, j'allais en mode 32 bits (avec des segments qui avaient une limite d'un meg).

Merci pour les suggestions!

Terry

+1

Indice: acceptez votre propre réponse lorsque cela se produit. 17 mars. 102010-03-17 21:13:07