Я не могу переключиться в защищенный режим в программе DOS EXE, написанной на MASM.
При загрузке дескриптора DOSBox выдает ошибку:
Недопустимый тип дескриптора 0 int 0.
Я создал функцию для загрузки таблицы дескрипторов с тремя дескрипторами Null, Code, Data. И я даже включил линию A20. У меня проблемы сразу после использования инструкции LGIT. Мой код:
.386p
GDT struct
limit_0_15 word ?
base_0_15 word ?
base_16_23 byte ?
access_byt byte ?
fl_limit byte ?
base_24_31 byte ?
GDT ends
main_data segment use16
idt_start:
db 800h dup (?)
idt_info:
dw 2048
dd idt_start
gdt_start:
nul_gdt GDT <0,0,0,0,0,0>
c32_gdt GDT <0,0,0,0,0,0>
d32_gdt GDT <0,0,0,0,0,0>
gdt_info:
dw gdt_info - gdt_start - 1
dd gdt_start
main_data ends
main_code segment use16
assume cs:main_code, ds:main_data, ss:stack16
_start:
mov ax,main_data
mov ds,ax
mov ax,code16
mov es,ax
call es:[Check_A20]
call es:[Set_A20]
call es:[Check_A20]
call es:[Create_GDT]
mov bx,gdt_info
lgdt fword ptr[bx]
mov bx,idt_info
lidt fword ptr[bx]
mov eax,cr0
or eax,1
mov cr0,eax
jmp clear_prefetch_queue
nop
nop
clear_prefetch_queue:
mov eax,0ffffh
mov ebx,0fh
div ebx
exit:
mov ah,4ch
int 21h
main_code ends
code16 segment use16
Wait_8042_command proc ; wait for the kbd controller to get ready to take in commands
in al,64h
test al,2
jnz Wait_8042_command
ret
Wait_8042_command endp
Wait_8042_data proc ; wait for the kbd controller to get ready to take in data
in al,64h
test al,1
jz Wait_8042_data
ret
Wait_8042_data endp
Check_A20 proc
pushf
push ds
push es
push di
push si
cli
xor ax,ax
mov es,ax
mov di,500h
not ax
mov ds,ax
mov si,510h
mov al,byte ptr es:[di]
push ax
mov al,byte ptr ds:[si]
push ax
mov byte ptr es:[di],0
mov byte ptr ds:[si],0ffh
cmp byte ptr es:[di],0ffh
pop ax
mov byte ptr ds:[si],al
pop ax
mov byte ptr es:[di],al
mov ax,0
je check_a20_exit
mov ax,1
check_a20_exit:
pop si
pop di
pop es
pop ds
popf
retf
Check_A20 endp
Set_A20 proc
cli
call Wait_8042_command
mov al,0ADh ;set command to disable kbd
out 64h,al
call Wait_8042_command
mov al,0d0h
out 64h,al ;read from input
call Wait_8042_data
in al,60h ;read input from kbd
push ax
call Wait_8042_command
mov al,0d1h ;write to output
out 64h,al
call Wait_8042_command
pop ax
or al,2
out 60h,al
call Wait_8042_command
mov al,0AEh ;enable kbd controller
out 64h,al
call Wait_8042_command
sti
retf
Set_A20 endp
Create_GDT proc
push ds
mov ax,main_data
mov ds,ax
;NULL Descriptor
;mov cx,4
;rep stosw
;code32 gdt initialized
mov c32_gdt.limit_0_15, 0ffffh
mov c32_gdt.base_0_15, 0h
mov c32_gdt.base_16_23, 0h
mov c32_gdt.access_byt, 9ah
mov c32_gdt.fl_limit, 0cfh
mov c32_gdt.base_24_31, 0h
;data32 gdt initialized
mov d32_gdt.limit_0_15, 0ffffh
mov d32_gdt.base_0_15, 0h
mov d32_gdt.base_16_23, 0h
mov d32_gdt.access_byt, 92h
mov d32_gdt.fl_limit, 0cfh
mov d32_gdt.base_24_31, 0h
pop ds
retf
Create_GDT endp
code16 ends
code32 segment use32
mov eax,0ffffh ;test garbage
mov ebx,0fh
div ebx
code32 ends
data32 segment use32
data32 ends
stack16 segment stack use16
dw 200h dup (?)
stack16 ends
end _start