Страница 1 из 1

Проблемы со стеком в PM

Добавлено: 06 июн 2006, 02:30
C0DiCK
Посмотрите пожалуйста на код, отвечающий за инициализацию сегмента стэка и определение регистра ESP. В нём есть ошибка. В коментариях есть предыдущий код. Он хоть и рабочий, но явно с ошибкой. Там было написано:
MOV AH, Flags1
TASM подставлял вместо Flags1 значение 5. В результате регистр ESP загружался следующим значением:
StackBase + StackLimit - 15 + 50000h
Сразу видно, что это неправильно, но ЭТО РАБОТАЛО. Когда я пытаюсь сделать правильный код, который вы модете увидеть в TMB.asm, компьютер перезагружается, когда программа использует стэк. Кто-нибудь что-нибудь знает? Проверьте, пожалуйста.

Добавлено: 06 июн 2006, 17:55
BBB
А что есть TMB.asm ???

Добавлено: 07 июн 2006, 02:08
C0DiCK
Прошу прощения за столь грубую ошибку. Исправлюсь :cry: .
Для удобства:
.586P
.MODEL LARGE

CODE SEGMENT USE16 ;16-битный сегмент кода
ORG 100h
ASSUME CS:CODE, DS:CODE, ES:CODE, SS:CODE
;===================================================================================================
START:
PUSH CS
PUSH CS
PUSH CS
POP DS
POP ES
POP SS

;определение базы сегмента кода
MOV EAX, CS
SHL EAX, 04h
ADD AX, OFFSET PM_ENTRY
MOV EBX, OFFSET hCode
MOV [EBX].Base15_00, AX
SHR EAX, 16
MOV [EBX].Base23_16, AL
MOV [EBX].Base31_24, AH

;определение базы и лимита сегмента данных
MOV EAX, CS
SHL EAX, 04h
ADD AX, OFFSET DATA
MOV EBX, OFFSET hData
MOV [EBX].Base15_00, AX
SHR EAX, 16
MOV [EBX].Base23_16, AL
MOV [EBX].Base31_24, AH
MOV AX, DataLen
MOV [EBX].Limit15_00, AX

;загрузка регистра GDT
MOV EAX, CS
SHL EAX, 04h
ADD AX, OFFSET Null
MOV EBX, OFFSET GDTR_GDTREG
MOV DWORD PTR [EBX].OFFS, EAX
LGDT FWORD PTR GDTR_GDTREG

;подготовка описателя исключения "нет сегмента"(0Bh)
MOV EBX, OFFSET NoSeg
MOV EAX, CS
ADD AX, OFFSET NoSegP
MOV [EBX].OFFS15_00, AX
SHR EAX, 16
MOV [EBX].OFFS31_16, AX
MOV [EBX].SEL, 08h
MOV [EBX].ACCESS, 10001110b

;подготовка описателя исключения "ошибка стека"(0Ch)
MOV EBX, OFFSET StackEr
MOV EAX, CS
ADD AX, OFFSET StackErP
MOV [EBX].OFFS15_00, AX
SHR EAX, 16
MOV [EBX].OFFS31_16, AX
MOV [EBX].SEL, 08h
MOV [EBX].ACCESS, 10001110b

MOV EBX, OFFSET IDTR_IDTREG
MOV [EBX].Limit, IDT_size-1
MOV [EBX].OFFS, OFFSET IDT

;подготовка описателя исключения "общая безопасность"(0Dh)
MOV EBX, OFFSET GlobSec
MOV EAX, CS
ADD AX, OFFSET GlobSecP
MOV [EBX].OFFS15_00, AX
SHR EAX, 16
MOV [EBX].OFFS31_16, AX
MOV [EBX].SEL, 08h
MOV [EBX].ACCESS, 10001110b

;инициализация контроллеров прерываний
CALL InitControlers

LIDT IDTR_IDTREG

;Включение адресной линии A20:
IN AL, 92h
OR AL, 02h
OUT 92h, AL

;Обнуление регистра флагов:
push byte 2
popf

; запретить немаскируемое прерывание
IN AL, 70h ;индексный порт CMOS
OR AL, 80h ;установка бита 7 в нем запрещает NMI
OUT 70h, AL

cli


;определение базы сегмента стэка CodeBase + CodeLimit + 5
MOV EBX, OFFSET hCode
XOR EAX, EAX
MOV AH, [EBX].Base31_24
MOV AL, [EBX].Base23_16
SHL EAX, 16
MOV AX, [EBX].Base15_00
XOR EDX, EDX
MOV DH, [EBX].Flags2
AND DH, 00001111b
SHL EDX, 8
MOV DX, [EBX].Limit15_00
ADD EAX, EDX
ADD EAX, 5
MOV EBX, OFFSET hStack
MOV [EBX].Base15_00, AX
SHR EAX, 16
MOV [EBX].Base23_16, AL
MOV [EBX].Base31_24, AH

;Сейчас: определяем верхушку стэка StackLimit - 15
;Раньше: определяем верхушку стэка StackBase + StackLimit - 15
; MOV DH, [EBX].Base31_24
; MOV DL, [EBX].Base23_16
; SHL EDX, 16
; MOV DX, [EBX].Base15_00
XOR EAX, EAX
;Сейчас:
MOV AH, [EBX].Flags2
;Раньше: MOV AH, Flags1
AND AH, 00001111b
SHL EAX, 8
MOV AX, [EBX].Limit15_00
; ADD EAX, EDX
SUB EAX, 15

;загружаем верхушку стэка
MOV ESP, EAX


;переход в защищённый режим
MOV EAX, CR0
OR AL, 00000001b
MOV CR0, EAX

;МЫ В ЗАЩИЩЁННОМ РЕЖИМЕ С З А П Р Е Щ Ё Н Н Ы М И ПРЕРЫВАНИЯМИ
;загружаем в CS селектор данного сегмента
DB 66h
DB 0EAh ;Код команды far jmp
DD 0h ;DD offset PM_ENTRY ;Смещение
DW 1000b ;Селектор сегмента команд

;===================================================================================================
NoSegP PROC
POP EAX

MOV AX, 00011000b
MOV ES, AX
MOV DI, 0
MOV AL, 30h
MOV ES:[DI], AL
INC DI
MOV ES:[DI], AL
INC DI
MOV ES:[DI], AL
INC DI
MOV ES:[DI], AL

CLI ;запретить прерывания
MOV AL, 20h ;команда EOI(разблокиравать контроллер аппаратных прерываний)
OUT 20h, AL ;в контроллер прерываний

IRET ;Interrupt Return(автоматически разрешает прерывания)
NoSegP ENDP
;===================================================================================================
StackErP PROC
POP EAX

MOV AX, 00011000b
MOV ES, AX
MOV DI, 0
MOV AL, 31h
MOV ES:[DI], AL
INC DI
MOV ES:[DI], AL
INC DI
MOV ES:[DI], AL
INC DI
MOV ES:[DI], AL

CLI ;запретить прерывания
MOV AL, 20h ;команда EOI(разблокиравать контроллер аппаратных прерываний)
OUT 20h, AL ;в контроллер прерываний

IRET ;Interrupt Return(автоматически разрешает прерывания)
StackErP ENDP
;===================================================================================================
GlobSecP PROC
POP EAX

MOV AX, 00011000b
MOV ES, AX
MOV DI, 0
MOV AL, 32h
MOV ES:[DI], AL
INC DI
MOV ES:[DI], AL
INC DI
MOV ES:[DI], AL
INC DI
MOV ES:[DI], AL

CLI ;запретить прерывания
MOV AL, 20h ;команда EOI(разблокиравать контроллер аппаратных прерываний)
OUT 20h, AL ;в контроллер прерываний

IRET ;Interrupt Return(автоматически разрешает прерывания)
GlobSecP ENDP
;===================================================================================================
InitControlers PROC NEAR
;Инициализация ведущего контроллера прерываний
MOV DX, 20h ;первый порт ведущего контроллера прерываний
MOV AL, 11h ;посылаем первое слово инициализации контроллера прерываний
OUT DX, AL ;в ведущий контроллер прерываний

JMP $ + 2 ;задержка
INC DX ;переходим ко второму порту ведущего контроллера прерываний
MOV AL, 20h ;устанавливаем базовый адрес для ведущего контроллера прерываний
OUT DX, AL ;равным 20h

JMP $ + 2 ;задержка
MOV AL, 00000100b ;1b - номер IRQ от ведомого контроллера прерываний
OUT DX, AL ;0b - номера IRQ от периферийных устройств

JMP $ + 2 ;задержка
MOV AL, 01h ;блокировка прерываний нижлежащих уровней осуществляется
OUT DX, AL ;командой EOI(00h - автоматически)

JMP $ + 2 ;задержка
MOV AL, VedushM ;устанавливаем маску прерываний для ведущего контроллера прерываний
OUT DX, AL ;0b - разрещено, 1b - запрещено

;Инициализация ведомого контроллера прерываний
MOV DX, 0A0h ;первый порт ведомого контроллера прерываний
MOV AL, 11h ;посылаем первое слово инициализации контроллера прерываний
OUT DX, AL ;в ведомый контроллер прерываний

JMP $ + 2 ;задержка
INC DX ;переходим ко второму порту ведомого контроллера прерываний
MOV AL, 70h ;устанавливаем базовый адрес для ведомого контроллера прерываний
OUT DX, AL ;равный 70h

JMP $ + 2 ;задержка
MOV AL, 10b ;1b - номер IRQ для ведомого контроллера прерываний
OUT DX, AL ;0b - номера IRQ от периферийных устройств

JMP $ + 2 ;задержка
MOV AL, 01h ;блокировка прерываний нижлежащих уровней осуществляется
OUT DX, AL ;командой EOI(00h - автоматически)

JMP $ + 2 ;задержка
MOV AL, VedomM ;устанавливаем маску прерываний для ведомого контроллера прерываний
OUT DX, AL ;0b - разрещено, 1b - запрещено

RET
InitControlers ENDP
;===================================================================================================
DATA:
;===================================================================================================
GDTREG STRUC ;Global Description Table Register
Limit DW ? ;лимит таблицы GDT
OFFS DD ? ;биты 31-00 смещения таблицы GDT
GDTREG ENDS
GDI STRUC ;Global Description Item
Limit15_00 DW ? ;биты 15-00 лимита сегмента
Base15_00 DW ? ;биты 15-00 базы сегмента
Base23_16 DB ? ;биты 23-16 базы сегмента
;флаги [7 - P - 7] [6 - DPL - 5] [4 - S - 4] [3 - TYPE - 0]
; P - 0 отсутствует, 1 присутствует; S - 0 системный, 1 код или данные
Flags1 DB ?
;флаги [7 - G - 7] [6 - D/B - 6] [5 - O - 5] [4 - AVL - 4] [3 - Limit19_16 - 0]
; G - 0 в байтах, 1 в 4 Кб
Flags2 DB ?
Base31_24 DB ? ;биты 31-24 базы сегмента
GDI ENDS
IDI STRUC ;Interrupt Descriptor Item
OFFS15_00 DW ? ;биты 15-00 смещения обработчика прерывания
SEL DW ? ;селектор сегмента
PARAM_CNT DB ? ;нулевой
ACCESS DB ? ;[7 - присутствие - 7]
;[6 - уровень привилегий - 5]
;[4 - тип дескриптора - 4]
;[3 - тип шлюза - 0]
OFFS31_16 DW ? ;биты 31-16 смещения обработчика прерывания
IDI ENDS
IDTREG STRUC ;Interrupt Description Table Register
Limit DW ? ;лимит таблицы IDT
OFFS DD ? ;биты 31-00 смещения таблицы IDT
IDTREG ENDS
;---------------------------------------------------------------------------------------------------
IDT LABEL WORD
Int0 IDI <0,8,0,0,0>
Int1 IDI <0,8,0,0,0>
Int2 IDI <0,8,0,0,0>
Int3 IDI <0,8,0,0,0>
Int4 IDI <0,8,0,0,0>
Int5 IDI <0,8,0,0,0>
Int6 IDI <0,8,0,0,0>
Int7 IDI <0,8,0,0,0>
Int8 IDI <0,8,0,0,0>
Int9 IDI <0,8,0,0,0>
IntA IDI <0,8,0,0,0>
NoSeg IDI <0,0,0,0,0>
StackEr IDI <0,0,0,0,0>
GlobSec IDI <0,0,0,0,0>
IDT_size=$-IDT

IDTR_IDTREG IDTREG <0,0>
GDTR_GDTREG GDTREG <39, 0h>
Null GDI <0h, 0h, 0h, 0h, 0h, 0h>
hCode GDI <0FFh, 0h, 0h, 10011010b, 01000000b, 0h>
hStack GDI <0FFh, 0h, 0h, 10010110b, 01000000b, 0h>
Video GDI <0FFFFh, 8000h, 0Bh, 10010010b, 0h, 0h>
hData GDI <00h, 00h, 0h, 10010010b, 0h, 0h>

mLimit DB 39
;---------------------------------------------------------------------------------------------------
VedushM DB 11000011b ;маска ведущего контроллера прерываний
VedomM DB 11111111b ;маска ведомого контроллера прерываний
;---------------------------------------------------------------------------------------------------
DStrL DB 'Protected Mode is ON!!!!!!!', 0
;===================================================================================================
DataLen=$-DATA
;===================================================================================================
PM_ENTRY:
CODE ENDS
;===================================================================================================
;===================================================================================================
PM SEGMENT USE32
ASSUME CS:PM
continue:
MOV AX, 10000b
MOV SS, AX

MOV EAX, 250
MOV ESP, EAX

CALL Func32
RET
;===================================================================================================
Func32 PROC NEAR
;Звуковой сигнал
Or AL , 3H ;вкл
Out 61H , AL ;ючаем
mov AL , 15 ;задаём
Out 61H , AL ;звук
; And AL , 0FCH ;вык
; Out 61H , AL ;лючаем
JMP $
Func32 ENDP
PM ENDS

END START[/img][/url]