Comment utiliser GDB en mode 16 bits?

J’ai le code suivant, où j’essaye d’implémenter une fonction qui affiche une chaîne en utilisant les fonctions du BIOS:

int printSsortingng(char* ssortingng) { int i = 0; while (*(ssortingng + i) != '\0') { char al = *(ssortingng + i); char ah = 0xe; int ax = ah * 256 + al; interrupt(0x10,ax,0,0,0); i++; } return i; } 

L’interruption de fonction est implémentée dans l’assemblage. Il appelle l’interruption du BIOS appropriée, comme indiqué par le premier argument, avec le rest des arguments contenant le contenu des registres ax, bx, cx et dx, respectivement:

 .global _interrupt _interrupt: push bp mov bp, sp push si push ds mov ax, #0x100 mov ds, ax mov ax, [bp + 0x4] mov si, #intr mov [si + 1], al pop ds mov ax, [bp + 0x6] mov bx, [bp + 0x8] mov cx, [bp + 0xa] mov dx, [bp + 0xc] intr: int #0x0 pop si pop bp ret 

Depuis que j’utilise les interruptions du BIOS, j’utilise le mode 16 bits pour comstackr ce code. J’ai utilisé la commande suivante:

 bcc -ansi -c -o printSsortingng.o printSsortingng.c 

Je veux tester ce code dans GDB, mais lorsque j’essaie de charger ce fichier printSsortingng.o dans gdb à l’aide de:

 gdb printSsortingng.o 

Je reçois l’erreur suivante:

“/home/kern/printSsortingng.o”: pas au format exécutable: format de fichier non reconnu

J’ai aussi essayé de changer le format GDB au format 16 bits en utilisant:

 set architecture i8086 

Mais toujours cette erreur est à venir. Comment puis-je charger un code 16 bits dans GDB?

Comme le dit Jester dans les commentaires, vous ne pouvez pas exécuter de fichier object avec gdb .

Et vous ne pouvez pas exécuter de fichier exécutable 16 bits ni de code d’assemblage 16 bits avec gdb . vous devez utiliser quelque chose comme qemu pour exécuter votre code sur un processeur émulé et vous y connecter à l’aide de gdb ou vous pouvez utiliser dosbox pour exécuter votre code et utiliser le programme de débogage sous dos. et rappelez-vous que l’utilisation des interruptions du BIOS est une erreur du système d’exploitation moderne comme Linux, car au démarrage ces systèmes d’exploitation désactivent les interruptions du BIOS.

Exemple QEMU minimal

 qemu-system-i386 -hda main.img -S -s & gdb -ex 'target remote localhost:1234' \ -ex 'set architecture i8086' \ -ex 'break *0x7c00' \ -ex 'continue' 

main.img est un secteur de démarrage .

  • break *0x7c00 : la première instruction ne sera pas votre secteur de démarrage, mais plutôt 0x0000fff0 qui effectue la configuration du BIOS, voir aussi . Nous utilisons donc cela pour commencer à partir duquel le secteur de démarrage est chargé.
  • set architecture i8086 : pour les exécutables ELF normaux, GDB peut choisir l’architecture à partir des en-têtes. Mais pour les secteurs de démarrage bruts, il n’existe pas de telles métadonnées, nous devons donc les indiquer.

Voir également:

  • Comment obtenir des informations de débogage au niveau source: Comment procéder au débogage au niveau source du code x86 avec GDB dans QEMU?
  • Questions similaires: Débogage basé sur qemu de bas niveau || Déboguer qemu avec gdb || Débogage du chargeur de démarrage avec gdb dans qemu
  • Quelques autres bonnes idées: https://stackoverflow.com/a/32960272/895245
  • Comment franchir int : Comment passer des appels d’interruption lors du débogage d’un chargeur d’amorçage / bios avec gdb et QEMU?