Форум программистов, компьютерный форум, киберфорум
Assembler: DOS/Real Mode/16-bits
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/12: Рейтинг темы: голосов - 12, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 28.11.2019
Сообщений: 8
TASM

Защищённый режим: написать обработчик особой ситуации 11 (сегмент не присутствует)

12.10.2020, 19:42. Показов 2615. Ответов 2

Студворк — интернет-сервис помощи студентам
Подтолкните, пожалуйста, в нужное направление. Разбираюсь с этим уже больше недели, ничего толкового в инете не нахожу. Не понимаю вообще как вызывается особая ситуация в защищённом режиме. Саму суть, вроде бы, понимаю, что в реальном режиме, если (по задаче) бит Р = 0, то вызывается особая ситуация 11, но вот как её самому вызывать в ЗЗ не понимаю

Дано задание:
Написать обработчик особой ситуации 11 (сегмент не присутствует), выводящий соответствующее сообщение на экран. Для проверки его работы создать в GDT дескриптор не присутствующего сегмента и обратиться к нему.

Дан код, в который нужно внести изменения по текущему заданию (уже создал дескриптор с байтом доступа, где P = 0):
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
;Программа транслируется в COM - файл:
; TASM demo.asm
; Tlink demo.obj /t
; Demo.asm
.386p                               ; Разрешение трансляции
                                    ; всех инструкций 80386
Gdt_Descriptor  STRUC               ; Шаблон дескриптора GDT
   Seg_Limit       dw   0             ; Длина сегмента
   Base_Lo_Word    dw   0             ; Младшие 16 бит базового
                                      ; адреса
   Base_Hi_Byte    db   0             ; Биты 16..23 базового адр.
   Acces_Rights    db   0             ; Байт прав доступа
   Limit&Acces     db   0             ;         +
   Base_Top_Byte   db   0             ; Биты 24..31 базового адр.   !
Gdt_Descriptor  ENDS
 
Idt_Descriptor  STRUC                ; Шаблон дескриптора IDT
   Int_Offset      dw   0              ; Точка входа в процедуру
                                       ;  обработки прерывания
   Int_Selector    dw   0              ; Селектор сегмента в GDT
                   db   0              ;
   Access          db   0              ; Права доступа
                   dw   0              ;
Idt_Descriptor  ENDS
 
Code_Seg_Access  Equ  10011011b      ; Байт прав  доступа деск-
                                     ; риптора сегмента кода
Data_Seg_Access  Equ  10010011b      ; Байт прав  доступа деск-
                                     ; риптора сегмента данных
Disable_Bit20    Equ  11011101b      ; Код команды 8042 для за-
                                     ; крывания линии A20
Enable_Bit20     Equ  11011111b      ; Код команды 8042 для от-
                                     ; крывания линии A20
Port_A           Equ  060h           ; Порт A 8042
Status_port      Equ  064h           ; Порт состояния 8042
Cmos_Port        Equ  070h           ; Адрес порта CMOS-памяти
 
; Макро для записи базового адреса сегмента в дескриптор
FILLDESCR MACRO   Seg_Addr,Offset_Addr,Descr
           xor     edx,edx                 ; EDX := 0
           xor     ecx,ecx                 ; ECX := 0
           mov     dx,Seg_Addr             ; Сегментная часть
           mov     cx,offset Offset_Addr   ; Смещение
           call    Form_32Bit_Address      ; CX:DX := линейный
                                           ; адрес
           mov     &Descr.Base_Lo_Word,dx  ; Занесение базового
           mov     &Descr.Base_Hi_Byte,cl  ; адреса в дескрип-
           mov     &Descr.Base_Top_Byte,ch ; тор      !
ENDM
 
CSEG       SEGMENT  Para USE16 public 'code'
           ASSUME  cs:Cseg,ds:Cseg
           org 100h
 
start: jmp Main
    
;********************** НАЧАЛО ДАННЫХ **********************
; Глобальная дескрипторная таблица GDT
 EVEN
 Gdt    label   word
 
;********** Дескриптор, описывающий саму таблицу GDT **********
 Gdt_Desc       EQU $-gdt            ; Селектор дескриптора
 Gdt1           Gdt_Descriptor <gdt_leng-1,,,data_seg_access,>;    !
 
;****** Дескриптор, описывающий сегмент Cseg как кодовый ******
 Cs_Code        EQU $-gdt            ; Селектор дескриптора
 Gdt2           Gdt_Descriptor<0FFFFh,,,code_seg_access,>;   !
 
;** Дескриптор, описывающий Cseg как сегмент данных с пределом*
;** 0FFFEh. Он будет использоваться также в роли стекового. ***
 Cs_Data        EQU $-gdt            ; Селектор дескриптора
 Gdt3           Gdt_Descriptor<0FFFFh,,,data_seg_access,>; !
 
SSEG_SELECTOR        EQU $-gdt            ; Селектор дескриптора
 Gdt4           Gdt_Descriptor<511,,,data_seg_access,>;
 
;***********************************************************************
;                         ЗАДАНИЕ ВАРИАНТ 5  
;                            Дескриптор
;***********************************************************************
Hidden_Seg_Access Equ 00011011b; Старший бит - бит P = 0
Ss_Stack EQU $-gdt
Gdt5 Gdt_Descriptor<0FFFFH,,,hidden_seg_access,>
;***********************************************************************
 
;************* Дескриптор, описывающий таблицу IDT *************
 Idt_Pointer    Gdt_Descriptor<idt_leng-1,,,data_seg_access>
 
;** Дескриптор, описывающий таблицу IDT реального режима *******
 Idt_Real       Gdt_Descriptor<3FFh,,,data_seg_access>
 
;********* Дескриптор, описывающий сегмент видеопамяти *********
 Video_Desc     EQU $-gdt            ; Селектор дескриптора
 GdtB800        Gdt_Descriptor<0FFFh,8000h,0bh,data_seg_access>;  !
 
Gdt_Leng        EQU $-gdt            ; Длина таблицы GDT
 
;Таблица дескрипторов прерываний IDT.
 EVEN
 Idt   label   word
 ex0     Idt_Descriptor<offset ex0_proc,cs_code,0,10000111b,0>
 ex1     Idt_Descriptor<offset ex1_proc,cs_code,0,10000111b,0>
 ex2     Idt_Descriptor<offset ex2_proc,cs_code,0,10000110b,0>
 ex3     Idt_Descriptor<offset ex3_proc,cs_code,0,10000111b,0>
 ex4     Idt_Descriptor<offset ex4_proc,cs_code,0,10000111b,0>
 ex5     Idt_Descriptor<offset ex5_proc,cs_code,0,10000111b,0>
 ex6     Idt_Descriptor<offset ex6_proc,cs_code,0,10000111b,0>
 ex7     Idt_Descriptor<offset ex7_proc,cs_code,0,10000111b,0>
 ex8     Idt_Descriptor<offset ex8_proc,cs_code,0,10000111b,0>
 ex9     Idt_Descriptor<offset ex9_proc,cs_code,0,10000111b,0>
 ex10    Idt_Descriptor<offset ex10_proc,cs_code,0,10000111b,0>
 ex11    Idt_Descriptor<offset ex11_proc,cs_code,0,10000111b,0>
 ex12    Idt_Descriptor<offset ex12_proc,cs_code,0,10000111b,0>
 ex13    Idt_Descriptor<offset ex13_proc,cs_code,0,10000111b,0>
 ex14    Idt_Descriptor<offset ex14_proc,cs_code,0,10000111b,0>
 ex15    Idt_Descriptor<offset ex15_proc,cs_code,0,10000111b,0>
 ex16    Idt_Descriptor<offset ex16_proc,cs_code,0,10000111b,0>
         Idt_Descriptor 22 dup(<>)
 Int39   Idt_Descriptor<offset int10_proc,cs_code,0,10000110b,0>
 Idt_Leng       EQU $-Idt            ; Длина таблицы IDT
 
Real_Jump          dd  ?           ; Адрес межсегментного
                                   ; перехода в реальном режиме
Protect_Jump       dd  ?           ; Адрес межсегментного пере-
                                   ; хода в защищенном режиме
Mess               db  'Special Event 11$'
 
Gate_Failure       db "Error open A20$"
 
;********************** КОНЕЦ ДАННЫХ **********************
 
Main:
           FillDescr  cs,Gdt,Gdt1    ; !!!Формирование 32-разряд-
                                     ; ного адреса из CS:GDT и
                                     ; запись его в дескриптор
                                     ; с номером Gdt_Desc.
           FillDescr  cs,0,gdt2      ; Дескриптор Cs_Code ука-
                                     ; зывает на CSEG как на
                                     ; кодовый сегмент.
           FillDescr  cs,0,gdt3      ; !!!Дескриптор Cs_Data ука-
                                     ; зывает на CSEG как на
                                     ; сегмент данных.
           FillDescr  cs,0,gdt4;!!!!  
           FillDescr  cs,Idt,Idt_Pointer ; !!!!Дескриптор Idt_Pointer
                                         ; указывает на IDT.
;***********************************************************************
;                         ЗАДАНИЕ ВАРИАНТ 5  
;             дескриптор dgt5 указывает на CSEG как на сегмент стека 
;***********************************************************************
           FillDescr cs, 0, gdt5;
;***********************************************************************
 
           cli                       ; Запрет прерываний
           mov     al,8fh            ; Запрет немаскируемых
           out     cmos_port,al      ; прерываний
           jmp     short $+2
 
           mov     ah,Enable_Bit20        ; Открываем адрес-
           call    Gate_A20               ; ную линию A20
           or      al,al                  ; Если произошла
           jz      A20_Opened             ; ошибка, то
           mov     dx,offset Gate_Failure ; выдать сообщение
           mov     ah,9                   ; на экран, разре-
           int     21h                    ; шить прерывания и
           sti                            ; вернуться в DOS
           int     20h
A20_Opened:
           lea     di,Real_Jump           ; Формирование адреса
           mov     word ptr [di],offset Real ; для перехода
           mov     word ptr [di+2],cs        ; в реальный режим
           lea     di,Protect_Jump        ; Формирование адреса
           mov     word ptr [di], offset Protect ; для перехода
           mov     word ptr [di+2],Cs_Code       ; в защищенный
                                                 ; режим
           lgdt    Gdt1              ; Загрузка GDTR
           lidt    Idt_Pointer       ; Загрузка IDTR
           mov     eax,cr0           ; Переходим в защищенный
           or      eax,1             ; режим, устанавливая
           mov     cr0,eax           ; бит 0 в регистре CR0
           jmp     dword ptr Protect_Jump ; Переход на метку
                                          ; Protect
; Работа в защищенном режиме.
Protect:   mov     ax,Cs_Data
           mov     ss,ax             ; Регистры DS, ES и SS
           mov     ds,ax             ; содержат  селектор
           mov     es,ax             ; сегмента Cs_Data
           call    My_Proc           ; Вызов рабочей процедуры
           mov     eax,cr0           ; Переходим в реальный
           and     eax,0FFFFFFFEh    ; режим, сбрасывая бит 0   !
           mov     cr0,eax           ; регистра CR0
           jmp     dword ptr Real_Jump ; Косвенный межсегмент-
                                     ; ный переход на метку
                                     ; Real
; Работа в реальном режиме.
Real:      lidt    Idt_Real          ; Загружаем регистр IDTR
                                     ; для работы в реальном
                                     ; режиме
           mov     dx,cs             ; Восстанавливаем
           mov     ds,dx             ; сегментные
           mov     ss,dx             ; регистры
           mov     ah,Disable_Bit20  ; Закрытие адресной
           call    Gate_A20          ; линии A20
           sti                       ; Разрешение прерываний
           int     20h               ; Выход в DOS
 
ex0_proc:  iret                      ; Обработчики особых
ex1_proc:  iret                      ; ситуаций
ex2_proc:  iret                      ; Здесь установлены
ex3_proc:  iret                      ; заглушки вместо
ex4_proc:  iret                      ; обработчиков
ex5_proc:  iret
ex6_proc:  iret
ex7_proc:  iret
ex8_proc:  iret
ex9_proc:  iret
ex10_proc: iret
ex11_proc:
  pusha
  push    es
  push    Video_Desc        ; В регистр ES заносим се-
  pop     es                ; лектор сегмента видеопа-
                            ; мяти
  mov     dh,0fh            ; Очищаем экран
  call    Paint_Screen
  lea     bx,Mess           ; Адрес сообщения
  mov     dx,200Bh          ; Координаты вывода
  int     39d               ; Вывод строки на экран
  pop     es
  popa
  iret
ex12_proc: iret
ex13_proc: iret
ex14_proc: iret
ex15_proc: iret
ex16_proc: iret
 
;**************************************************************
;Управление прохождением сигнала A20
;ВХОД: (AH)=0DDH   установить A20 всегда равным нулю
;      (AH)=0DFh   открыть адресный разряд A20
;ВЫХОД: (AL)=0     8042 принял команду
;       (AH)=2     сбой
;**************************************************************
Gate_A20 PROC
           cli                       ; Запрет прерываний
           call    Empty_8042
           jnz     Gate_1
           mov     al,0d1h           ; Выдаем команду  8042 для
           out     Status_Port,al    ; записи в выходной порт
           call    Empty_8042
           jnz     Gate_1
           mov     al,ah             ; Записываем в порт A 8042
           out     Port_A,al         ; код команды
           call    Empty_8042
Gate_1:    ret
Gate_A20 ENDP
 
;**************************************************************
;Ждать пока буфер 8042 не опустеет
;Вход: нет
;Выход:(AL)=0   буфер пуст
;      (AL)=2   не пуст
;**************************************************************
Empty_8042  PROC
           push    cx
           xor     cx,cx             ; CX = 0 (256 повторений)
Empty_1:   in      al,Status_Port    ; Порт 8042
           and     al,00000010b      ; Бит 2 очищен ?
           loopnz  Empty_1
           pop     cx
           ret
Empty_8042  ENDP
 
;**************************************************************
; Формирование 32-разрядного адреса
; Вход : CX:DX - адрес в формате <сегмент:смещение>
; Выход: CX:DX - 32-разрядный линейный адрес
Form_32Bit_Address   PROC
           shl     edx,4
           add     edx,ecx
           mov     ecx,edx
           shr     ecx,16
           ret
Form_32Bit_Address   ENDP
 
;**************************************************************
;   Процедура вывода строки на экран, работает в качестве
;   обработчика прерывания.
; Вход : DS:BX - адрес сообщения
;        DL - строка экрана
;        DH - колонка экрана
;**************************************************************
Int10_Proc   Proc  Near              ; Обработчик прерывания
           pusha                     ; INT 39d
           xor     cx,cx             ; Очистка CX
           mov     cl,dh             ; CL = колонка
           sal     cl,1              ; CL = CL*2
           xor     dh,dh             ; DX = строка
           imul    dx,160d    ; Умножаем на число байт в строке
           add     dx,cx      ; Прибавляем смещение в строке
                              ; Результат: DX = смещение в
                              ; видеопамяти
           mov     di,dx      ; DI = смещение в этом сегменте
m:         mov     ax,[bx]    ; AL = очередной символ строки
           cmp     al,'$'     ; Конец строки ?
           jz      Ex         ; Да - выход
           mov     cx,es:[di] ; Получить атрибут в CH
           mov     ah,ch      ; AX = символ с атрибутом
           stosw              ; Записать символ в видеопамять
           inc     bx         ; Перейти к следующему символу
           jmp     short   m
ex:        popa
           iret               ; Возврат из прерывания
Int10_Proc Endp
 
;**************************************************************
;Процедура выполняющая какие-либо действия в защищенном режиме
;**************************************************************
MY_PROC    PROC
           pusha
           ;CALL ex11
           popa
           ret
MY_PROC ENDP
 
;**************************************************************
; Процедура очищает экран и устанавливает цвета в соответствии
; с заданным атрибутом.
; Вход : ES - селектор дескриптора текстового видеобуфера
;        DH - атрибут.
;**************************************************************
PAINT_SCREEN  PROC
           push    cx si di es
           mov     cx,80*25          ; Размер видеопамяти (слов)
           xor     si,si             ; SI и DI установим на
           xor     di,di             ; начало видеопамяти
Paint1:    lodsw                     ; Увеличиваем смещение в
                                     ; видеопамяти
           mov     ah,dh             ; Байт атрибута символа
           mov     al,20h            ; Код символа "ПРОБЕЛ"
           stosw                     ; Записываем символ с ат-
                                     ; рибутом в видеопамять
           loop    Paint1            ; Повторить для каждого
                                     ; символа на экране
           pop     es di si cx
           RET
PAINT_SCREEN ENDP
 
Cseg      Ends
End     start
В функцию, отвечающую за ос11 (ex11_proc) вставил код вывода сообщения, чтобы проверять, заходит программа вообще туда или нет
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
12.10.2020, 19:42
Ответы с готовыми решениями:

Защищённый режим ОС
Надеюсь, я верно выбрал раздел на форуме :) Меня интересует такой вопрос... Каким образом приложения типа ArtMoney могут получать доступ к...

Защищённый режим
Приветствую. Мне нужно написать программу, которая выполняет 3 действия в защищённом режиме: 1. Циклически выводить английский...

защищенный режим
а как можно изменить длину сегмента (предел) и потом снова считать его? Написать процедуру, меняющую в защищенном режиме предел ...

2
0 / 0 / 0
Регистрация: 28.11.2019
Сообщений: 8
17.10.2020, 02:26  [ТС]
Вроде бы сделал что-то более менее рабочее, но при выходе из функции ex11_proc при iret выдаёт ошибку, что неверный тип сегмента. Если же вместо iret написать ret, то ошибок нет, выводятся сообщения, но программа зацикливается

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
;Программа транслируется в COM - файл:
; TASM demo.asm
; Tlink demo.obj /t
; Demo.asm
.386p                               ; Разрешение трансляции
                                    ; всех инструкций 80386
Gdt_Descriptor  STRUC               ; Шаблон дескриптора GDT
   Seg_Limit       dw   0             ; Длина сегмента
   Base_Lo_Word    dw   0             ; Младшие 16 бит базового
                                      ; адреса
   Base_Hi_Byte    db   0             ; Биты 16..23 базового адр.
   Acces_Rights    db   0             ; Байт прав доступа
   Limit&Acces     db   0             ;         +
   Base_Top_Byte   db   0             ; Биты 24..31 базового адр.   !
Gdt_Descriptor  ENDS
 
Idt_Descriptor  STRUC                ; Шаблон дескриптора IDT
   Int_Offset      dw   0              ; Точка входа в процедуру
                                       ;  обработки прерывания
   Int_Selector    dw   0              ; Селектор сегмента в GDT
                   db   0              ;
   Access          db   0              ; Права доступа
                   dw   0              ;
Idt_Descriptor  ENDS
 
Code_Seg_Access  Equ  10011011b      ; Байт прав  доступа деск-
                                     ; риптора сегмента кода
Data_Seg_Access  Equ  10010011b      ; Байт прав  доступа деск-
                                     ; риптора сегмента данных
Data_Seg_Access_2 Equ  00010011b
 
Disable_Bit20    Equ  11011101b      ; Код команды 8042 для за-
                                     ; крывания линии A20
Enable_Bit20     Equ  11011111b      ; Код команды 8042 для от-
                                     ; крывания линии A20
Port_A           Equ  060h           ; Порт A 8042
Status_port      Equ  064h           ; Порт состояния 8042
Cmos_Port        Equ  070h           ; Адрес порта CMOS-памяти
 
; Макро для записи базового адреса сегмента в дескриптор
FILLDESCR MACRO   Seg_Addr,Offset_Addr,Descr
           xor     edx,edx                 ; EDX := 0
           xor     ecx,ecx                 ; ECX := 0
           mov     dx,Seg_Addr             ; Сегментная часть
           mov     cx,offset Offset_Addr   ; Смещение
           call    Form_32Bit_Address      ; CX:DX := линейный
                                           ; адрес
           mov     &Descr.Base_Lo_Word,dx  ; Занесение базового
           mov     &Descr.Base_Hi_Byte,cl  ; адреса в дескрип-
           mov     &Descr.Base_Top_Byte,ch ; тор      !
ENDM
 
CSEG       SEGMENT  Para USE16 public 'code'
           ASSUME  cs:Cseg,ds:Cseg
           org 100h
 
start: jmp Main
    
;********************** НАЧАЛО ДАННЫХ **********************
; Глобальная дескрипторная таблица GDT
 EVEN
 Gdt    label   word
 
;********** Дескриптор, описывающий саму таблицу GDT **********
 Gdt_Desc       EQU $-gdt            ; Селектор дескриптора
 Gdt1           Gdt_Descriptor <gdt_leng-1,,,data_seg_access,>;    !
 
;****** Дескриптор, описывающий сегмент Cseg как кодовый ******
 Cs_Code        EQU $-gdt            ; Селектор дескриптора
 Gdt2           Gdt_Descriptor<0FFFFh,,,code_seg_access,>;   !
 
;** Дескриптор, описывающий Cseg как сегмент данных с пределом*
;** 0FFFEh. Он будет использоваться также в роли стекового. ***
 Cs_Data        EQU $-gdt            ; Селектор дескриптора
 Gdt3           Gdt_Descriptor<0FFFFh,,,data_seg_access,>; !
 
SSEG_SELECTOR        EQU $-gdt            ; Селектор дескриптора
 Gdt4           Gdt_Descriptor<511,,,data_seg_access,>;
 
;** Дескриптор, описывающий Cseg как сегмент данных с пределом*
;** 0FFFEh. Он будет использоваться также в роли стекового. ***
 Cs_Data_2        EQU $-gdt            ; Селектор дескриптора
 Gdt3_2           Gdt_Descriptor<0FFFFh,,,data_seg_access_2,>; !
 
;************* Дескриптор, описывающий таблицу IDT *************
 Idt_Pointer    Gdt_Descriptor<idt_leng-1,,,data_seg_access>
 
;** Дескриптор, описывающий таблицу IDT реального режима *******
 Idt_Real       Gdt_Descriptor<3FFh,,,data_seg_access>
 
;********* Дескриптор, описывающий сегмент видеопамяти *********
 Video_Desc     EQU $-gdt            ; Селектор дескриптора
 GdtB800        Gdt_Descriptor<0FFFh,8000h,0bh,data_seg_access>;  !
 
Gdt_Leng        EQU $-gdt            ; Длина таблицы GDT
 
;Таблица дескрипторов прерываний IDT.
 EVEN
 Idt   label   word
 ex0     Idt_Descriptor<offset ex0_proc,cs_code,0,10000111b,0>
 ex1     Idt_Descriptor<offset ex1_proc,cs_code,0,10000111b,0>
 ex2     Idt_Descriptor<offset ex2_proc,cs_code,0,10000110b,0>
 ex3     Idt_Descriptor<offset ex3_proc,cs_code,0,10000111b,0>
 ex4     Idt_Descriptor<offset ex4_proc,cs_code,0,10000111b,0>
 ex5     Idt_Descriptor<offset ex5_proc,cs_code,0,10000111b,0>
 ex6     Idt_Descriptor<offset ex6_proc,cs_code,0,10000111b,0>
 ex7     Idt_Descriptor<offset ex7_proc,cs_code,0,10000111b,0>
 ex8     Idt_Descriptor<offset ex8_proc,cs_code,0,10000111b,0>
 ex9     Idt_Descriptor<offset ex9_proc,cs_code,0,10000111b,0>
 ex10    Idt_Descriptor<offset ex10_proc,cs_code,0,10000111b,0>
 ex11    Idt_Descriptor<offset ex11_proc,cs_code,0,10000111b,0>
 ex12    Idt_Descriptor<offset ex12_proc,cs_code,0,10000111b,0>
 ex13    Idt_Descriptor<offset ex13_proc,cs_code,0,10000111b,0>
 ex14    Idt_Descriptor<offset ex14_proc,cs_code,0,10000111b,0>
 ex15    Idt_Descriptor<offset ex15_proc,cs_code,0,10000111b,0>
 ex16    Idt_Descriptor<offset ex16_proc,cs_code,0,10000111b,0>
         Idt_Descriptor 22 dup(<>)
 Int39   Idt_Descriptor<offset int10_proc,cs_code,0,10000110b,0>
 Idt_Leng       EQU $-Idt            ; Длина таблицы IDT
 
Real_Jump          dd  ?           ; Адрес межсегментного
                                   ; перехода в реальном режиме
Protect_Jump       dd  ?           ; Адрес межсегментного пере-
                                   ; хода в защищенном режиме
event11            db  'Missing segment$'
Mess               db  'PROTECTED MODE$'
 
Gate_Failure       db "Error open A20$"
 
;********************** КОНЕЦ ДАННЫХ **********************
 
Main:
           FillDescr  cs,Gdt,Gdt1    ; !!!Формирование 32-разряд-
                                     ; ного адреса из CS:GDT и
                                     ; запись его в дескриптор
                                     ; с номером Gdt_Desc.
           FillDescr  cs,0,gdt2      ; Дескриптор Cs_Code ука-
                                     ; зывает на CSEG как на
                                     ; кодовый сегмент.
           FillDescr  cs,0,gdt3      ; !!!Дескриптор Cs_Data ука-
                                     ; зывает на CSEG как на
                                     ; сегмент данных.
           FillDescr  cs,0,gdt4;!!!! 
 
           FillDescr  cs, 0,gdt3_2
 
           FillDescr  cs,Idt,Idt_Pointer ; !!!!Дескриптор Idt_Pointer
                                         ; указывает на IDT.
 
           cli                       ; Запрет прерываний
           mov     al,8fh            ; Запрет немаскируемых
           out     cmos_port,al      ; прерываний
           jmp     short $+2
 
           mov     ah,Enable_Bit20        ; Открываем адрес-
           call    Gate_A20               ; ную линию A20
           or      al,al                  ; Если произошла
           jz      A20_Opened             ; ошибка, то
           mov     dx,offset Gate_Failure ; выдать сообщение
           mov     ah,9                   ; на экран, разре-
           int     21h                    ; шить прерывания и
           sti                            ; вернуться в DOS
           int     20h
A20_Opened:
           lea     di,Real_Jump           ; Формирование адреса
           mov     word ptr [di],offset Real ; для перехода
           mov     word ptr [di+2],cs        ; в реальный режим
           lea     di,Protect_Jump        ; Формирование адреса
           mov     word ptr [di], offset Protect ; для перехода
           mov     word ptr [di+2],Cs_Code       ; в защищенный
                                                 ; режим
           lgdt    Gdt1              ; Загрузка GDTR
           lidt    Idt_Pointer       ; Загрузка IDTR
           mov     eax,cr0           ; Переходим в защищенный
           or      eax,1             ; режим, устанавливая
           mov     cr0,eax           ; бит 0 в регистре CR0
           jmp     dword ptr Protect_Jump ; Переход на метку
                                          ; Protect
; Работа в защищенном режиме.
Protect:   
           mov     ax, Cs_Data_2
           mov     ax,Cs_Data
           mov     ss,ax             ; Регистры DS, ES и SS
           mov     ds,ax             ; содержат  селектор
           mov     es,ax             ; сегмента Cs_Data
           call    My_Proc           ; Вызов рабочей процедуры
           mov     eax,cr0           ; Переходим в реальный
           and     eax,0FFFFFFFEh    ; режим, сбрасывая бит 0   !
           mov     cr0,eax           ; регистра CR0
           jmp     dword ptr Real_Jump ; Косвенный межсегмент-
                                     ; ный переход на метку
                                     ; Real
; Работа в реальном режиме.
Real:      lidt    Idt_Real          ; Загружаем регистр IDTR
                                     ; для работы в реальном
                                     ; режиме
           mov     dx,cs             ; Восстанавливаем
           mov     ds,dx             ; сегментные
           mov     ss,dx             ; регистры
           mov     ah,Disable_Bit20  ; Закрытие адресной
           call    Gate_A20          ; линии A20
           sti                       ; Разрешение прерываний
           int     20h               ; Выход в DOS
 
ex0_proc:  iret                      ; Обработчики особых
ex1_proc:  iret                      ; ситуаций
ex2_proc:  iret                      ; Здесь установлены
ex3_proc:  iret                      ; заглушки вместо
ex4_proc:  iret                      ; обработчиков
ex5_proc:  iret
ex6_proc:  iret
ex7_proc:  iret
ex8_proc:  iret
ex9_proc:  iret
ex10_proc: iret
ex11_proc:
  lea     bx,event11        ; Адрес сообщения
  mov     dx,200Dh          ; Координаты вывода
  int     39d               ; Вывод строки на экран
  iret
ex12_proc: iret
ex13_proc: iret
ex14_proc: iret
ex15_proc: iret
ex16_proc: iret
 
;**************************************************************
;Управление прохождением сигнала A20
;ВХОД: (AH)=0DDH   установить A20 всегда равным нулю
;      (AH)=0DFh   открыть адресный разряд A20
;ВЫХОД: (AL)=0     8042 принял команду
;       (AH)=2     сбой
;**************************************************************
Gate_A20 PROC
           cli                       ; Запрет прерываний
           call    Empty_8042
           jnz     Gate_1
           mov     al,0d1h           ; Выдаем команду  8042 для
           out     Status_Port,al    ; записи в выходной порт
           call    Empty_8042
           jnz     Gate_1
           mov     al,ah             ; Записываем в порт A 8042
           out     Port_A,al         ; код команды
           call    Empty_8042
Gate_1:    ret
Gate_A20 ENDP
 
;**************************************************************
;Ждать пока буфер 8042 не опустеет
;Вход: нет
;Выход:(AL)=0   буфер пуст
;      (AL)=2   не пуст
;**************************************************************
Empty_8042  PROC
           push    cx
           xor     cx,cx             ; CX = 0 (256 повторений)
Empty_1:   in      al,Status_Port    ; Порт 8042
           and     al,00000010b      ; Бит 2 очищен ?
           loopnz  Empty_1
           pop     cx
           ret
Empty_8042  ENDP
 
;**************************************************************
; Формирование 32-разрядного адреса
; Вход : CX:DX - адрес в формате <сегмент:смещение>
; Выход: CX:DX - 32-разрядный линейный адрес
Form_32Bit_Address   PROC
           shl     edx,4
           add     edx,ecx
           mov     ecx,edx
           shr     ecx,16
           ret
Form_32Bit_Address   ENDP
 
;**************************************************************
;   Процедура вывода строки на экран, работает в качестве
;   обработчика прерывания.
; Вход : DS:BX - адрес сообщения
;        DL - строка экрана
;        DH - колонка экрана
;**************************************************************
Int10_Proc   Proc  Near              ; Обработчик прерывания
           pusha                     ; INT 39d
           xor     cx,cx             ; Очистка CX
           mov     cl,dh             ; CL = колонка
           sal     cl,1              ; CL = CL*2
           xor     dh,dh             ; DX = строка
           imul    dx,160d    ; Умножаем на число байт в строке
           add     dx,cx      ; Прибавляем смещение в строке
                              ; Результат: DX = смещение в
                              ; видеопамяти
           mov     di,dx      ; DI = смещение в этом сегменте
m:         mov     ax,[bx]    ; AL = очередной символ строки
           cmp     al,'$'     ; Конец строки ?
           jz      Ex         ; Да - выход
           mov     cx,es:[di] ; Получить атрибут в CH
           mov     ah,ch      ; AX = символ с атрибутом
           stosw              ; Записать символ в видеопамять
           inc     bx         ; Перейти к следующему символу
           jmp     short   m
ex:        popa
           iret               ; Возврат из прерывания
Int10_Proc Endp
 
;**************************************************************
;Процедура выполняющая какие-либо действия в защищенном режиме
;**************************************************************
MY_PROC    PROC
           pusha
            push    es
            push    Video_Desc        ; В регистр ES заносим се-
            pop     es                ; лектор сегмента видеопа-
                                      ; мяти
            mov     dh,0fh            ; Очищаем экран
            call    Paint_Screen
            lea     bx, mess           ; Адрес сообщения
            mov     dx,200Ch          ; Координаты вывода
            int     39d               ; Вывод строки на экран
 
            mov ax, cs_data_2
            mov ds, ax
 
            pop     es
            popa
            
           ret
MY_PROC ENDP
 
;**************************************************************
; Процедура очищает экран и устанавливает цвета в соответствии
; с заданным атрибутом.
; Вход : ES - селектор дескриптора текстового видеобуфера
;        DH - атрибут.
;**************************************************************
PAINT_SCREEN  PROC
           push    cx si di es
           mov     cx,80*25          ; Размер видеопамяти (слов)
           xor     si,si             ; SI и DI установим на
           xor     di,di             ; начало видеопамяти
Paint1:    lodsw                     ; Увеличиваем смещение в
                                     ; видеопамяти
           mov     ah,dh             ; Байт атрибута символа
           mov     al,20h            ; Код символа "ПРОБЕЛ"
           stosw                     ; Записываем символ с ат-
                                     ; рибутом в видеопамять
           loop    Paint1            ; Повторить для каждого
                                     ; символа на экране
           pop     es di si cx
           RET
PAINT_SCREEN ENDP
 
Cseg      Ends
End     start
Миниатюры
Защищённый режим: написать обработчик особой ситуации 11 (сегмент не присутствует)   Защищённый режим: написать обработчик особой ситуации 11 (сегмент не присутствует)  
0
7 / 6 / 1
Регистрация: 12.10.2021
Сообщений: 397
28.11.2022, 12:24
Я из будущего,решил проблему?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.11.2022, 12:24
Помогаю со студенческими работами здесь

Защищенный режим
Доброе время суток, помогите с таким заданием, заранее большое спасибо: - проверка присутствия сегмента; - проверка защиты от загрузки...

защищенный режим
люди разъясните кто знает.надо переключить проц в защищенный режим работы. часть кода code segment ...... db 0eah ;(1)машинный...

защищенный режим
Как преобразовать программу из формата .COM в формат .EXE.?

Написать обработчик исключений ситуации при преобразовании указателя на класс B до указателя на абстрактный класс А ...
Написать обработчик исключений ситуации при преобразовании указателя на класс B до указателя на абстрактный класс А ... как сделать...

Защищенный режим DOS - С++
Нужна помощь!!! Надо написать программу на С++ для защищенного режима DOS. В проге надо записать данные в переменную до 100 мб а потом...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru