¿Cómo usar GDB en modo de 16 bits?

4 minutos de lectura

avatar de usuario
sarthak

Tengo el siguiente código, donde intento implementar una función que imprime una cadena usando las funciones del BIOS:

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

La función de interrupción se implementa en ensamblador. Llama a la interrupción de BIOS apropiada, como lo indica el primer argumento, y el resto de los argumentos contienen los contenidos para los registros ax, bx, cx y dx respectivamente:

.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

Como estoy usando interrupciones de BIOS, estoy usando el modo de 16 bits para compilar este código. Utilicé el siguiente comando:

bcc -ansi -c -o printString.o printString.c

Quiero probar este código en GDB, pero cuando trato de cargar este archivo printString.o en gdb usando:

gdb printString.o

Obtuve el siguiente error:

“/home/kern/printString.o”: no en formato ejecutable: formato de archivo no reconocido

También intenté cambiar el formato GDB a 16 bits usando:

set architecture i8086

Pero todavía viene este error. ¿Cómo puedo cargar un código de 16 bits en GDB?

  • No puede ejecutar archivos de objetos en gdb, no importa cuántos bits. Debe crear un ejecutable, como dice el mensaje de error. Para el código de 16 bits, también necesitará un entorno de 16 bits, como qemu.

    – bufón

    2 de marzo de 2015 a las 14:15


  • @Jester Pero se usa en modo de 32 bits con gcc. El comando gcc -g program.c -o programname se usa para generar un código objeto y se ejecuta usando gdb programname

    – Sarthak

    2 de marzo de 2015 a las 15:07

  • Si, ahora juega spot the difference con las dos líneas de comando. Note que el gcc uno hace no tener -c y produce ejecutable (también insinuado por la falta .o extensión) pero su bcc hace tener el -c (que significa compilar a objeto) y también la salida tiene el .o extensión.

    – bufón

    2 de marzo de 2015 a las 15:08

  • @Jester ok … También intenté vincular usando el comando ld86. Pero sigue mostrando el mismo error. ¿Ld86 no produce código ejecutable? ¿No hay otra forma de convertir el archivo .o en ejecutable y usarlo en GDB?

    – Sarthak

    2 de marzo de 2015 a las 15:21

  • ld86 produce un ejecutable, pero ese es un ejecutable de 16 bits que no puede cargar en su sistema operativo nativo (que no especificó, pero supongo que Linux). Para el sistema operativo, eso no califica como ejecutable. Es por eso que necesita algo que pueda ejecutar su código de 16 bits y proporcionar los servicios de BIOS esperados. Esto es lo que qemu, bochs o dosbox puede hacer.

    – bufón

    2 de marzo de 2015 a las 15:24

avatar de usuario
Ciro Santilli Путлер Капут 六四事

Ejemplo mínimo de QEMU

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

donde main.img es un sector de arranque.

  • break *0x7c00: la primera instrucción no será su sector de arranque, sino más bien 0x0000fff0 que hace la configuración del BIOS, consulte también. Entonces usamos esto para comenzar desde donde se carga el sector de arranque.
  • set architecture i8086: para ejecutables ELF normales, GDB puede decidir la arquitectura a partir de los encabezados. Pero para los sectores de arranque sin procesar, no existen tales metadatos, por lo que tenemos que informarlo.

Ver también:

  • Cómo obtener información de depuración de nivel de fuente: ¿Cómo hacer la depuración de nivel de fuente del código x86 con GDB dentro de QEMU?
  • Preguntas similares: depuración basada en qemu de bajo nivel || Depurar qemu con gdb || Depuración del gestor de arranque con gdb en qemu
  • Algunas buenas ideas más: https://stackoverflow.com/a/32960272/895245
  • como pasar por encima int: ¿Cómo pasar por alto las llamadas de interrupción al depurar un gestor de arranque/bios con gdb y QEMU?

avatar de usuario
Parham Alvani

Como dice Jester en los comentarios, no puede ejecutar un archivo de objeto con gdb.

Y no puede ejecutar un archivo ejecutable de 16 bits o un código ensamblador de 16 bits con gdb. Debes usar algo como qemu para ejecutar su código en una CPU emulada y conectarse a ella usando gdbo puedes usar dosbox para ejecutar su código y usar un programa de depuración en DOS. Y recuerde, el uso de interrupciones de BIOS es un error en un sistema operativo moderno, como Linux, porque al iniciarse, estos sistemas operativos desactivan las interrupciones de BIOS.

  • BOCHS tiene un buen depurador incorporado (documentos). Es muy recomendable para el desarrollo de gestores de arranque; entiende la segmentación (a diferencia de GDB) y puede analizar e imprimir las tablas IDT / GDT / página para que pueda verificar que almacenó los datos correctos en ellas. También puede mostrarle detalles de excepciones.

    – Peter Cordes

    23 mayo 2020 a las 19:15

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad