berezin
Зарегистрирован: 29.11.2004 Сообщения: 1 Откуда: г.Саров, Россия
|
Добавлено: Пн Ноя 29 2004 18:12 Заголовок сообщения: Переключение процессора в PROTECT MODE, проблема со стеком |
|
|
Здравствуйте.
Я начал изучение защищенного режима, написал программу
переключающую процессор в PROTECT MODE (код см. ниже) и
вот, что получилось.
В PM перехожу нормально, но дальше любая попытка поместить.
что либо в стек приводит к #GPF с последующей перезагрузкой.
Помогите, пожалуйста разобраться с проблемой.
---------------------- Вот код --------------------
Код: |
;-------------------------------------
; Программа перевода процессора
; в защащенный режим
;-------------------------------------
masm
.586P
.model small
GDT_Pointer struc ; Структура регистра GDTR
Limit dw 39
Base dd 0
GDT_Pointer ends
Descriptor struc ; Структура дескриптора
Limit dw 0FFFFh
Base1 dw 0
Base2 db 0
AR_Byte db 0
Attr db 0
base3 db 0
Descriptor ends
LoadDescriptor macro descr, Base, AR
xor eax, eax
mov ax, Base
shl eax, 4
mov descr.Base1, ax
rol eax, 16
mov descr.Base2, al
mov al, AR
mov descr.AR_Byte, al
endm
dseg segment para public use16
; Описание глобальной дескрипторной таблицы
;---------------------------------------------
descr_null Descriptor <0,,,,,>
descr_ss8 Descriptor <1FFh,,,,,>
descr_es10 Descriptor <>
descr_ds18 Descriptor <>
descr_cs20 Descriptor <>
;---------------------------------------------
Pointer GDT_Pointer <>
Msg1 db "Working in protect mode!", 0
dseg ends
stk segment stack use16
db 200h dup(0)
stk ends
cseg segment para public use16
assume cs:cseg; ss:stk
Start:
assume ds:dseg
;-------- Формируем глобальную дескрипторную таблицу ------
mov ax, dseg
mov ds, ax
mov ax, stk
mov ss, ax
LoadDescriptor descr_ss8, stk, 10010110b
LoadDescriptor descr_es10, 0B800h, 10010010b
LoadDescriptor descr_ds18, dseg, 10010010b
LoadDescriptor descr_cs20, cseg, 10011000b
;----- Обязательно запретить прерывания чтобы не зависнуть -----
cli
in al, 70h
or al, 80h
out 70h, al
;----- Загружаем регистр GDTR -----
xor eax, eax
mov ax, dseg
shl eax, 4
mov dword ptr Pointer.Base, eax
lgdt pword ptr Pointer
;-------- Теперь все готово и мы переключаемся в PROTECT MODE
mov eax, cr0
or eax, 1
mov cr0, eax
;-------- Загружаем теневые дескрипторы -------
db 0EAh
dw offset Protect
dw 20h
Protect: ; Первая команда выполняемая в PROTECT MODE
mov ax, 8
mov ss, ax
mov ax, 10h
mov es, ax
mov ax, 18h
mov ds, ax
mov sp, 1FFh
;-------- Сообщаем об успешном переходе --------
mov di, 1920 ; Позиция вывода
mov si, offset Msg1 ; Адрес строки
; --- Эта команда вызывает #GPF ---
; --- Пробовал заменять ее на PUSH AX с тем же успехом ---
call Print
;-------- Звучим -------
call Beep
;-------- Вешаемся ---------
hlt
;----------- Вспомогательные прцедуры -------------
Print proc near
hlt
mov ah, 7
@@00:
mov al, [si]
and al, al
jz @@99
mov word ptr es:[di], ax
inc si
add di, 2
jmp @@00
@@99:
ret
Print endp
Beep proc near
in al, 61h
or al, 3
out 61h, al
mov ecx, 0F0000000h
@@01:
loop @@01
and al, 0FCh
out 61h, al
ret
Beep endp
cseg ends
end Start
|
|
|
FUKS
Зарегистрирован: 14.04.2002 Сообщения: 148 Откуда: Москва
|
Добавлено: Вт Ноя 30 2004 18:42 Заголовок сообщения: Re: Переключение процессора в PROTECT MODE, проблема со стеком |
|
|
Никогда не имел дела с Protected Mode на практике, но собаку разглядел:
Что значит 1FFh? Во-первых, указатель стека должен быть кратен разрядности слова в текущем режиме (для защищённого режима по умолчанию 32 бита=4 байта), т.е. младшие два бита sp должны быть нулями, иначе уже на GPF тянет (вероятно). А главное (если невыравненность sp прокатила), при лимите в 1FFh и sp=1FFh имеет место обращение к последовательности из 4 байтов: 1FFh,200h,201h,202h - тривиальныое нарушение лимита. Так что
Да и сам лимит стека мягко говоря маловат будет, тем более для защищённого режима. |
|