Ошибка: недопустимый дескриптор типа 0 для int 0 - PullRequest
1 голос
/ 24 марта 2019

Я не могу переключиться в защищенный режим в программе 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
...