Actualmente estoy jugando con x86 Assember para agudizar mis habilidades de programación de bajo nivel. Actualmente, estoy enfrentando un pequeño problema con el esquema de direccionamiento en modo protegido de 32 bits.Assembler salta en Modo protegido con GDT
La situación es la siguiente:
Tengo un programa cargado en 0x7e0 que cambia la CPU para el modo protegido y salta a la etiqueta de acuerdo en el código:
[...]
code to switch CPU in Protected Mode
[...]
jmp ProtectedMode
[...]
bits 32
ProtectedMode:
.halt:
hlt
jmp .halt
Esto funciona absolutamente bien por lo lejos. El "JMP ProtectedMode" funciona sin un salto lejano explícito para borrar la cola de captación previa, ya que este programa está cargado con el desplazamiento 0 (org 0 al comienzo), lo que hace que el segmento de código apunte a la ubicación correcta.
Mi problema actual ahora es que dentro de la etiqueta "ProtectedMode" quiero saltar a otro programa que se carga en 0x8000 (lo comprobé con un volcado de memoria, la función de carga funcionó correctamente y el programa está cargado correctamente a 0x8000).
Dado que la CPU ahora está en Modo Protegido y no en RealMode, el esquema de direccionamiento es diferente. ProtectedMode utiliza selectores de descriptores para buscar una dirección base y un límite en una tabla de descriptores para agregar el desplazamiento dado y recuperar la dirección física (según entendí). Por lo tanto, fue necesario instalar un GDT antes de ingresar a ProtectedMode.
mina está buscando como el siguiente:
%ifndef __GDT_INC_INCLUDED__
%define __GDT_INC_INCLUDED__
;*********************************
;* Global Descriptor Table (GDT) *
;*********************************
NULL_DESC:
dd 0 ; null descriptor
dd 0
CODE_DESC:
dw 0xFFFF ; limit low
dw 0 ; base low
db 0 ; base middle
db 10011010b ; access
db 11001111b ; granularity
db 0 ; base high
DATA_DESC:
dw 0xFFFF ; data descriptor
dw 0 ; limit low
db 0 ; base low
db 10010010b ; access
db 11001111b ; granularity
db 0 ; base high
gdtr:
Limit dw 24 ; length of GDT
Base dd NULL_DESC ; base of GDT
%endif ;__GDT_INC_INCLUDED__
y se carga a la GDT registrarse a través
lgdt [gdtr]
Lo que no entiendo hasta ahora es, ¿cómo puedo Ahora salta a la física dirección 0x8000 en ProtectedMode usando el GDT?
Mis primeros pensamientos fueron seleccionar el Descriptor de Código (CODE_DESC) que debería apuntar a 0x7e00 (se cargó el programa actual) y utilizar el desplazamiento necesario para obtener 0x8000 (512 bytes), lo que da como resultado la instrucción de salto :
jmp CODE_DESC:0x200
Pero esto no funciona.
jmp 0x7e0:0x200
no funciona bien ...
¿Tiene alguna idea de lo que me falta aquí? Tal vez no entendí algo esencial dentro del esquema de direccionamiento de 32-Bit ProtectedMode y el uso del GDT.
[EDIT] Código completo:
bits 16
org 0 ; loaded with offset 0000 (phys addr: 0x7e00)
jmp Start
Start:
xor ax, ax
mov ax, cs
mov ds, ax ; update data segment
cli ; clear interrupts
lgdt [gdtr] ; load GDT from GDTR (see gdt_32.inc)
call OpenA20Gate ; open the A20 gate
call EnablePMode ; jumps to ProtectedMode
;******************
;* Opens A20 Gate *
;******************
OpenA20Gate:
in al, 0x93 ; switch A20 gate via fast A20 port 92
or al, 2 ; set A20 Gate bit 1
and al, ~1 ; clear INIT_NOW bit
out 0x92, al
ret
;**************************
;* Enables Protected Mode *
;**************************
EnablePMode:
mov eax, cr0
or eax, 1
mov cr0, eax
jmp ProtectedMode ; this works (jumps to label and halts)
;jmp (CODE_DESC-NULL_DESC):ProtectedMode ; => does not work
;jmp 08h:ProtectedMode , => does not work
;***************
;* data fields *
;* &includes *
;***************
%include "gdt_32.inc"
;******************
;* Protected Mode *
;******************
bits 32
ProtectedMode:
;here I want to jump to physical addr 0x8000 (elf64 asm program)
.halt:
hlt
jmp .halt
Gracias por la explicación ... Esta es exactamente la razón por la que estoy haciendo esto, y no es tan simple cuando se hace esto desde cero por primera vez simplemente leyendo referencias x86 :)! Por cierto: ¿hay algún gran libro que pueda aconsejar que maneje exactamente este tipo de temas? –
No sé buenos libros. La documentación oficial de Intel y AMD tiene toda la información, simplemente no es un tipo típico de libro o libro de texto que leería fácilmente y comprendería todo de inmediato (por cierto, hay muchos errores ortográficos y errores ocasionales en los documentos de Intel). Hay muchos artículos y tutoriales en línea. Y siempre puedes experimentar O vea el código de alguien y haga preguntas. Vea estos grupos: [alt.os.development] (http://groups.google.com/group/alt.os.development/topics), [comp.lang.asm.x86] (http://groups.google .com/group/comp.lang.asm.x86/topics). –
¡Gracias por tu consejo! Echaré un vistazo a eso! –