usar ruta instalar ensamblado descargar assembly x86 nasm gdt

assembly - ruta - ¿Cómo ingreso al modo protegido de 32 bits en el ensamblado NASM?



ruta gacutil exe (1)

La programación de un sistema operativo es una tarea avanzada. Al menos se espera que pueda usar un depurador para encontrar sus propios errores y comprender las cosas básicas. Es posible que desee reconsiderar si tiene todos los requisitos previos para este esfuerzo.

Dicho esto, tienes los siguientes problemas:

  1. Usted asume que el código está cargado en 0x7c00:0 debido a la org 0 , pero ese podría no ser el caso. Lo único garantizado es la dirección física. Debe usar un salto lejano a su punto de entrada para que CS esté configurado correctamente.
  2. Por alguna razón, configura DS a 0x2000 para que su código no encuentre ningún dato. Debe configurar DS para que coincida con CS , o utilizar una anulación de CS todas partes (no recomendado).
  3. El código de modo protegido asume un segmento basado en cero, lo que a su vez significa que espera que org 0x7c00 por supuesto, entre en conflicto con su configuración. Deberías cambiar a org 0x7c00 y segmentos 0 .
  4. El segmento de modo de texto VGA está en 0xb8000 no en 0xb80000 (uno menos cero).
  5. No tiene los bytes de firma de inicio 0x55 0xaa al final del sector de inicio.

El código fijo:

[bits 16] [org 0x7c00] jmp 0:kernel_start gdt_start: gdt_null: dd 0x0 dd 0x0 gdt_code: dw 0xffff dw 0x0 db 0x0 db 10011010b db 11001111b db 0x0 gdt_data: dw 0xffff dw 0x0 db 0x0 db 10010010b db 11001111b db 0x0 gdt_end: gdt_descriptor: dw gdt_end - gdt_start dd gdt_start CODE_SEG equ gdt_code - gdt_start DATA_SEG equ gdt_data - gdt_start print: pusha mov ah, 14 mov bh, 0 .loop: lodsb cmp al, 0 je .done int 0x10 jmp .loop .done: popa ret uzenet16 db ''uzenet16'', 0 uzenet32 db ''uzenet32'', 0 kernel_start: mov ax, 0 mov ss, ax mov sp, 0xFFFC mov ax, 0 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov si, uzenet16 call print cli lgdt[gdt_descriptor] mov eax, cr0 or eax, 0x1 mov cr0, eax jmp CODE_SEG:b32 [bits 32] VIDEO_MEMORY equ 0xb8000 WHITE_ON_BLACK equ 0x0f print32: pusha mov edx, VIDEO_MEMORY .loop: mov al, [ebx] mov ah, WHITE_ON_BLACK cmp al, 0 je .done mov [edx], ax add ebx, 1 add edx, 2 jmp .loop .done: popa ret b32: mov ax, DATA_SEG mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax mov ebp, 0x2000 mov esp, ebp mov ebx, uzenet32 call print32 jmp $ [SECTION signature start=0x7dfe] dw 0AA55h

Su pregunta actualizada todavía parece estar confundida acerca de dónde se carga el código: usted dice offset 0x2000 pero luego habla sobre Executes the kernel using a far jump jmp 0x2000:0x0000 que es por supuesto incorrecto, porque tiene un cero más en el segmento, y debe ser un salto lejano de cero segmento de todos modos: jmp 0:0x2000 . Aparte de eso, verifique que su código efectivamente está cargado en la memoria en el lugar correcto. Aprende a usar un depurador.

Aquí hay un pequeño sector de arranque que carga el código anterior del segundo sector para dirigirse a 0x2000 . Funciona bien, el problema no está en las cosas de GDT, especialmente si ni siquiera se imprime el mensaje en modo real (tampoco estaba claro al respecto).

[bits 16] [org 0x7c00] mov ax, 0201h mov cx, 0002h mov dh, 0 mov bx, 0 mov es, bx mov bx, 2000h int 13h jmp 0:2000h [SECTION signature start=0x7dfe] dw 0AA55h

Estoy aprendiendo ensamblaje x86, y estoy tratando de hacer un sistema operativo de juguete en NASM, pero no entiendo algunas cosas.

Hice un gestor de arranque que arranca con éxito mi kernel:

  1. Carga 14 sectores desde el disquete que contiene el archivo kernel;
  2. Busque un archivo en estos sectores etiquetados kernel.feo ;
  3. Carga ese archivo en la memoria en el desplazamiento 0x2000 ;
  4. Ejecuta el kernel usando un salto de jmp 0x2000:0x0000 .

Así que tengo el código del kernel ubicado en 0x2000:0 en la memoria. CS podría estar configurado correctamente debido al uso de un salto lejano. En este código del kernel, quiero ingresar al modo protegido de 32 bits, pero no estoy seguro de cómo funcionan los GDT. Cuando ejecuto el código siguiente en una máquina virtual (QEMU) , no hago nada.

¡Quiero complacerte por ayudarme a ingresar al modo protegido de 32 bits!

Dicho esto, tienes los siguientes problemas:

  1. Usted asume que el código está cargado en 0x7c00:0 debido a la org 0 , pero ese podría no ser el caso. Lo único garantizado es la dirección física. Debe usar un salto lejano a su punto de entrada para que CS esté configurado correctamente.
  2. Por alguna razón, configura DS a 0x2000 para que su código no encuentre ningún dato. Debe configurar DS para que coincida con CS , o utilizar una anulación de CS todas partes (no recomendado).
  3. El código de modo protegido asume un segmento basado en cero, lo que a su vez significa que espera que org 0x7c00 por supuesto, entre en conflicto con su configuración. Deberías cambiar a org 0x7c00 y segmentos 0 .
  4. El segmento de modo de texto VGA está en 0xb8000 no en 0xb80000 (uno menos cero).
  5. No tiene los bytes de firma de inicio 0x55 0xaa al final del sector de inicio.

He corregido estas cosas en mi código:

  1. [org 0x0] se corrige en [org 0x2000] y los segmentos se establecen en 0 ;
  2. DS se corrige a 0 lugar de 0x2000 , por lo que ahora coincide con CS ;
  3. El segmento del modo de texto VGA está corregido a 0xb8000 ;

Pero el código no funcionará con estas correcciones, debería imprimir dos cadenas pero ¡no hace nada!

Tenga en cuenta que este código de kernel no debe terminar con una firma de inicio 0x55 0xAA , porque no es un sector de arranque.

Aquí está el código corregido del kernel (que no funciona):

[bits 16] [org 0x2000] jmp 0:kernel_start gdt_start: gdt_null: dd 0x0 dd 0x0 gdt_code: dw 0xffff dw 0x0 db 0x0 db 10011010b db 11001111b db 0x0 gdt_data: dw 0xffff dw 0x0 db 0x0 db 10010010b db 11001111b db 0x0 gdt_end: gdt_descriptor: dw gdt_end - gdt_start dd gdt_start CODE_SEG equ gdt_code - gdt_start DATA_SEG equ gdt_data - gdt_start print: mov ah, 14 mov bh, 0 lodsb cmp al, 0 je .done int 0x10 jmp print .done: ret uzenet_real db ''uzenet16'', 0 uzenet_prot db ''uzenet32'', 0 kernel_start: mov ax, 0 mov ss, ax mov sp, 0xFFFC mov ax, 0 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov si, uzenet_real call print cli lgdt[gdt_descriptor] mov eax, cr0 or eax, 0x1 mov cr0, eax jmp CODE_SEG:b32 [bits 32] VIDEO_MEMORY equ 0xb8000 WHITE_ON_BLACK equ 0x0f print32: pusha mov edx, VIDEO_MEMORY .loop: mov al, [ebx] mov ah, WHITE_ON_BLACK cmp al, 0 je .done mov [edx], ax add ebx, 1 add edx, 2 jmp .loop .done: popa ret b32: mov ax, DATA_SEG mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax mov ebp, 0x90000 mov esp, ebp mov ebx, uzenet_prot call print32 jmp $