Пишу простую прогу для защищенного режима. Пока нахожусь в нул
евом кольце - все работает отлично, как только меняю DPL у цел
евого сегмента с 0 на 3, выскакивает общее нарушение зашиты
Вот так все работает:
тут таблица д
ескрипторов:
STRUC desc_struc ; структура дескриптора
limit dw 0 ; предел
base_l dw 0 ; мл. слово физического адреса
base_h db 0 ; ст. байт физического адреса
access db 0 ; байт доступа
acces32 db 0
base_b db 0
ENDS desc_struc
ACC_PRESENT EQU 10000000b ; сегмент есть в памЯти
[hr]ACC_CSEG EQU 00011000b ; сегмент кода
ACC_DSEG EQU 00010000b ; сегмент данных
ACC_TSSSEG EQU 00001001b ; TSS
ACC_EXPDOWN EQU 00000100b ; сегмент расширЯетсЯ вниз
ACC_CONFORM EQU 00000100b ; согласованный сегмент
ACC_DATAWR EQU 00000010b ; разрешена запись
ACC_INTR_GATE EQU 00001110b ; вентиль прерываниЯ
ACC_TRAP_GATE EQU 00001111b ; вентиль исключениЯ
ACC_CALL_GATE EQU 00001100b
ACC_TASK_GATE EQU 00000101b
ACC_RING0 EQU 00000000b
ACC_RING3 EQU 01100000b
; ------------------------------------------------------------
; Типы сегментов
DATA_ACC = ACC_PRESENT OR ACC_DSEG OR ACC_DATAWR ; сегмент даннх
CODE_ACC = ACC_PRESENT OR ACC_CSEG ; сегмент кода
STACK_ACC = ACC_PRESENT OR ACC_DSEG OR ACC_DATAWR OR ACC_EXPDOWN ; сегмент стека
TSS_ACC = ACC_PRESENT OR ACC_TSSSEG ; TSS
IDT_ACC = DATA_ACC ; байт доступа сегмента таблицы IDT
INTR_ACC = ACC_PRESENT OR ACC_INTR_GATE ; байт доступа вентилЯ прерываниЯ
TRAP_ACC = ACC_PRESENT OR ACC_TRAP_GATE ; байт доступа вентилЯ исключениЯ
CALL_ACC = ACC_PRESENT OR ACC_CALL_GATE
TASK_ACC = ACC_PRESENT OR ACC_TASK_GATE
ACS_GRANUL EQU 10000000b
ACS_DIMENS EQU 01000000b
DATASEG
DSEG_BEG = THIS WORD
GDT_BEG = $
LABEL gdtr WORD
gdt_0 desc_struc <0,0,0,0,0,0>
gdt_gdt desc_struc <GDT_SIZE-1,,,DATA_ACC,0,0>
gdt_idt desc_struc <IDT_SIZE-1,,,IDT_ACC,0,0>
gdt_ds desc_struc <03fffh,,,DATA_ACC,0,0>
gdt_cs desc_struc <03fffh,,,CODE_ACC OR ACC_DATAWR,0,0>
gdt_ss desc_struc <03fffh,00000h,000h,DATA_ACC,ACS_DIMENS,0>
gdt_ds32 desc_struc <0ffffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 00Fh ,000h>
gdt_cs32 desc_struc <0ffffh,00000h,000h,CODE_ACC OR ACC_DATAWR OR ACC_RING0,ACS_GRANUL OR ACS_DIMENS OR 00Fh,000h>
gdt_ss32 desc_struc <0ffffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR ACS_DIMENS OR 00Fh,000h>
gdt_dsdebug desc_struc <0ffffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 00Fh ,000h>
gdt_csdebug desc_struc <0ffffh,00000h,000h,CODE_ACC OR ACC_DATAWR OR ACC_RING0,ACS_GRANUL OR ACS_DIMENS OR 00Fh,000h>
gdt_all desc_struc <0ffffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 00Fh ,000h>
gdt_tds32 desc_struc <0ffffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 00Fh ,000h>
gdt_tcs32 desc_struc <0ffffh,00000h,000h,CODE_ACC OR ACC_DATAWR OR ACC_RING0,ACS_GRANUL OR ACS_DIMENS OR 00Fh,000h>
gdt_tss32 desc_struc <0ffffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR ACS_DIMENS OR 00Fh,000h>
gdt_ssdebug desc_struc <0ffffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR ACS_DIMENS OR 00Fh,000h>
gdt_pzu desc_struc <007ffh,00000h,080h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 000h ,0ffh>
gdt_cpzu desc_struc <007ffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 000h ,0ffh>
gdt_ramq desc_struc <003ffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 000h ,080h>
gdt_ramx desc_struc <003ffh,00000h,080h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 000h ,080h>
gdt_ramy desc_struc <003ffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 000h ,081h>
gdt_ramz desc_struc <003ffh,00000h,080h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 000h ,081h>
gdt_tss_main desc_struc <06bh,,,TSS_ACC,0,0>
gdt_tss_task1 desc_struc <06bh,,,TSS_ACC,0,0>
gdt_tss_task2 desc_struc <06bh,,,TSS_ACC,0,0>
gdt_tss_task3 desc_struc <06bh,,,TSS_ACC,0,0>
gdt_tss_task4 desc_struc <06bh,,,TSS_ACC,0,0>
gdt_ds1 desc_struc <00001h,00000h,000h,DATA_ACC OR ACC_RING3,ACS_GRANUL OR 000h ,000h>
gdt_cs1 desc_struc <00002h,00000h,000h,CODE_ACC OR ACC_DATAWR OR ACC_RING0,ACS_GRANUL OR ACS_DIMENS OR 000h,000h>;селектор 0e0h
gdt_ss1 desc_struc <00003h,00000h,000h,DATA_ACC OR ACC_RING3,ACS_GRANUL OR ACS_DIMENS OR 000h,000h>
далее, перехожу в защищённый режим, инициализирую gdt_cs1 (адрес в памяти, предел), в нём по адресу 01010h размещаю код:
stlbpnt PROC far
mov dx, 1070h
mov eax,055h
out dx, eax
hlt
ret
stlbpnt ENDP
порт 1070h - введён спец
иально для отладки (это нестандартная ПК).
далее перехожу непосредственно на этот код:
DB 09ah
DD 01010h
DW 0e0h
по завершению из порта 1070h читаю 55h.
Здесь все работает на ура.
А так нет:
ввожу изменения:
...
gdt_cs1 desc_struc <00002h,00000h,000h,CODE_ACC OR ACC_DATAWR OR ACC_RING3,ACS_GRANUL OR ACS_DIMENS OR 000h,000h>;селектор 0e3h
...
DB 09ah
DD 01010h
DW 0e3h
После чего сразу выскакивает исключение 13. Порт 1070h остается без изменений.
Что
здесь нетак?