Форум программистов, компьютерный форум, киберфорум
Наши страницы
Assembler, MASM, TASM
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
ElvenDragon
3 / 8 / 1
Регистрация: 12.07.2009
Сообщений: 361
1

Будет ли прерывание int 21h работать в защищенном режиме

28.10.2012, 10:43. Просмотров 1082. Ответов 6
Метки нет (Все метки)

Будет ли прерывание int 21h функции ah=9 вывода строки работать в защищенном режиме?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.10.2012, 10:43
Ответы с готовыми решениями:

Действие int 21h
ааа ну вроде я понял вниз кароч отсчитываем пока не будет делимое число и количество отсчитываний и...

перехват int 21h
com 16 bit .286 ASKII_code_key_check equ 'A' ASKII_code_key equ 'B'...

Int 21h - 3Ah
можно создать .exe файл, способный удалить директорию, путь к которой приходит из консоли(другая...

Память в защищенном режиме
Всем доброго дня! Я, наконец, сдал основные экзамены и теперь снова могу заняться столь интересным...

Работа с файлами в защищенном режиме
Здравствуйте, я взялся писать ОС, уже готов загрузчик переводящий в защищенный режим процессор, IDT...

6
Kastaneda
Jesus loves me
Эксперт С++
5035 / 3047 / 349
Регистрация: 12.12.2009
Сообщений: 7,675
Записей в блоге: 2
Завершенные тесты: 1
28.10.2012, 15:05 2
Будет, только тебе нужно будет свой обработчик на 33 (21h) прерывание сделать.
0
Charles Kludge
Клюг
7647 / 3162 / 383
Регистрация: 03.05.2011
Сообщений: 8,382
28.10.2012, 15:12 3
Под DPMI - да. http://www.cyberforum.ru/post2784506.html
0
ElvenDragon
3 / 8 / 1
Регистрация: 12.07.2009
Сообщений: 361
28.10.2012, 17:02  [ТС] 4
Цитата Сообщение от Kastaneda Посмотреть сообщение
Будет, только тебе нужно будет свой обработчик на 33 (21h) прерывание сделать.
Несколько вопросов:
1.А можно например 15 или 16? Или обязательно 33?
2.Можно ли на один обработчик 2 разных прерывания?
Мне просто препод задал сделать такое задание. Перейти из реального режима в защищенный и там осуществить перемещение курсора. Я программу написал перемещение курсора но ток в реальном режиме и там используется 2 разных прерывания. Вот если я ее суну в качестве обработчика это не вызовет проблем? В данной программе используется два прерывания int 16h, int 10h.


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
.386p
 
data segment para public 'data' use16
data ends
 
stk segment para stack 'stk' use16
db 100h dup(?)
stk ends
 
code segment para public 'code' use16
assume cs:code, ds:data, ss:stk
start:
  mov ax,data  
  mov ds,ax
  
  ; устанавливаем текстовый видеорежим 80x25 и очищаем все видеостраницы
  xor eax,eax
  mov ax,3 
  int 10h
 
  ; получаем текущую позицию курсора
  xor eax,eax
  mov ah,3
  mov bh,0 ; видеостраница с которой получаем курсор и на которой устанавливаем курсор
  int 10h
  
  L1:
 
  ; функция задержки пока не будет считана клавиша в ax задержка будет продолжатся
  xor eax,eax
  mov ah,10h
  int 16h
  
  
  cmp ax,4BE0h ; <-
  jne S1
    ; функция смещения курсора влево
    cmp dl,0 ; если равно нулю то не можем влево смещать
    je SS1
      xor eax,eax      
      mov ah,2
      dec dl ; столбец
      int 10h
    SS1:
  S1:
 
  cmp ax,4DE0h ; ->
  jne S2
    ; функция смещения курсора вправо
    cmp dl,79 ; если равно 79 то не можем вправо смещать
    je SS2
      xor eax,eax      
      mov ah,2
      inc dl ; столбец
      int 10h
    SS2:
  S2:
 
  cmp ax,48E0h ; /\
  jne S3
    ; функция смещения курсора вверх
    cmp dh,0 ; если равно нулю то не можем вверх смещать
    je SS3
      xor eax,eax      
      mov ah,2
      dec dh ; строка
      int 10h
    SS3:
  S3:
 
  cmp ax,50E0h ; \/
  jne S4
    ; функция смещения курсора вниз
    cmp dh,24 ; если равно 24 то не можем вниз смещать
    je SS4
      xor eax,eax      
      mov ah,2
      inc dh ; строка
      int 10h
    SS4:
  S4:
  
  jmp L1 ; бесконечный цикл
 
  
ret
code ends
end start
Вот полный текст программы в защищенном режиме но он чет не осуществляет перемещение курсора в защищенном режиме. Вывод в видеопамять это типа проверки что я в защищенном режиме(если вдруг ошибку допущу).
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
.386p                                           ; разрешить привилегированные инструкции i386
        
; СЕГМЕНТ КОДА (для Real Mode)
; ---------------------------------------------------------------------------------------------------------
RM_CODE     segment     para public 'CODE' use16
        assume      CS:RM_CODE,SS:RM_STACK
start:
; очистка экрана:
                mov             AX,3
                int             10h
                
; открываем линию А20 (для 32-х битной адресации):
        in      AL,92h
        or      AL,2
        out     92h,AL
 
; вычисляем линейный адрес метки ENTRY_POINT (точка входа в защищенный режим):
        xor     EAX,EAX             ; обнуляем регистра EAX
        mov     AX,PM_CODE          ; AX = номер сегмента PM_CODE
        shl     EAX,4               ; EAX = линейный адрес PM_CODE
        add     EAX,offset ENTRY_POINT      ; EAX = линейный адрес ENTRY_POINT
        mov     dword ptr ENTRY_OFF,EAX     ; сохраняем его в переменной    
; (кстати, подобный "трюк" называется SMC или Self Modyfing Code - самомодифицирующийся код)
 
; теперь надо вычислить линейный адрес GDT (для загрузки регистра GDTR):
        xor     EAX,EAX
        mov     AX,RM_CODE          ; AX = номер сегмента RM_CODE
        shl     EAX,4               ; EAX = линейный адрес RM_CODE
        add     AX,offset GDT           ; теперь EAX = линейный адрес GDT
 
; линейный адрес GDT кладем в заранее подготовленную переменную:
        mov     dword ptr GDTR+2,EAX
 
; смещение прерывания
                xor     EAX,EAX
                mov             EAX,offset cursor
                mov             pre,AX
 
;IDTR
                xor     EAX,EAX
        mov     AX,RM_CODE          
        shl     EAX,4               
        add     AX,offset IDT   
 
; линейный адрес IDT кладем в заранее подготовленную переменную:
        mov     dword ptr IDTR+2,EAX
 
 
; собственно, загрузка регистра GDTR и IDTR:
        lgdt        fword  ptr GDTR
                lidt            fword  ptr IDTR
 
; запрет маскируемых прерываний:
        cli
 
; запрет немаскируемых прерываний:
        in      AL,70h
        or      AL,80h
        out     70h,AL
 
; переключение в защищенный режим:
        mov     EAX,CR0
        or      AL,1
        mov     CR0,EAX
 
; загрузить новый селектор в регистр CS
        db      66h             ; префикс изменения разрядности операнда
        db      0EAh                ; опкод команды JMP FAR
ENTRY_OFF   dd      ?               ; 32-битное смещение
        dw      00001000b           ; селектор первого дескриптора (CODE_descr)
 
; ТАБЛИЦА ГЛОБАЛЬНЫХ ДЕСКРИПТОРОВ:
GDT:  
; нулевой дескриптор (обязательно должен присутствовать в GDT!):
NULL_descr  db      8 dup(0)
CODE_descr  db      0FFh,0FFh,00h,00h,00h,10011010b,11001111b,00h
DATA_descr  db      0FFh,0FFh,00h,00h,00h,10010010b,11001111b,00h
VIDEO_descr      db              0FFh,0FFh,00h,80h,0Bh,10010010b,01000000b,00h
GDT_size    equ                 $-GDT               ; размер GDT
 
GDTR        dw      GDT_size-1          ; 16-битный лимит GDT
        dd      ?               ; здесь будет 32-битный линейный адрес GDT
 
IDT:
  dd 0, 0 ; 0
  dd 0, 0 ; 1
  dd 0, 0 ; 2
  dd 0, 0 ; 3
  dd 0, 0 ; 4
  dd 0, 0 ; 5
  dd 0, 0 ; 6
  dd 0, 0 ; 7
  dd 0, 0 ; 8
  dd 0, 0 ; 9
  pre dw 0, 08h, 1000111000000000b, 0 ; 10
  IDT_size equ $-IDT
  
IDTR dw IDT_size-1
     dd ?
 
RM_CODE         ends
; ---------------------------------------------------------------------------------------------------------
 
 
 
; СЕГМЕНТ СТЕКА (для Real Mode)
; ---------------------------------------------------------------------------------------------------------
RM_STACK       segment          para stack 'STACK' use32
           db          100h dup(?)                     ; 256 байт под стек - это даже много
RM_STACK       ends
; --------------------------------------------------------------------------------------------------------- 
 
 
 
; СЕГМЕНТ КОДА (для Protected Mode)
; ---------------------------------------------------------------------------------------------------------
PM_CODE     segment     para public 'CODE' use32
        assume      CS:PM_CODE,DS:PM_DATA
ENTRY_POINT:
; загрузим сегментные регистры селекторами на соответствующие дескрипторы:
                mov        AX,00010000b                ; селектор на второй дескриптор (DATA_descr)
            mov        DS,AX                       ; в DS его
                mov ss, ax
            mov        AX,00011000b                ; селектор на третий дескриптор (VIDEO_descr)
            mov        ES,AX                       ; а этого в ES
 
            xor            ESI,ESI                       ; обнуляем SI
            mov            SI,PM_DATA                  ; SI = номер сегмента PM_DATA
            shl            ESI,4                       ; ESI = линейный адрес сегмента PM_DATA
            add        ESI,offset message          ; ESI = линейный адрес строки message
                xor            EDI,EDI                     ; EDI = позиция на экране (относительно 0B8000h)
                
            mov        ECX,mes_len                 ; длина текста в ECX
 
; вывод на экран: 
            rep            movsb                       ; DS:ESI (наше сообщение) -> ES:EDI (видеопамять)
                
in al, 70h
and al, 7Fh
out 70h, al
sti
 
int 10
 
; обработчик
cursor: 
 
  ; получаем текущую позицию курсора
  xor eax,eax
  xor ebx,ebx
  mov ah,3
  mov bh,0 ; видеостраница с которой получаем курсор и на которой устанавливаем курсор
  int 10h
  
  L1:
 
  ; функция задержки пока не будет считана клавиша в ax задержка будет продолжатся
  xor eax,eax
  xor edx,edx
  mov ah,10h
  int 16h
  
  
  cmp ax,4BE0h ; <-
  jne S1
    ; функция смещения курсора влево
    cmp dl,0 ; если равно нулю то не можем влево смещать
    je SS1
      xor eax,eax      
      mov ah,2
      dec dl ; столбец
      int 10h
    SS1:
  S1:
 
  cmp ax,4DE0h ; ->
  jne S2
    ; функция смещения курсора вправо
    cmp dl,79 ; если равно 79 то не можем вправо смещать
    je SS2
      xor eax,eax      
      mov ah,2
      inc dl ; столбец
      int 10h
    SS2:
  S2:
 
  cmp ax,48E0h ; /\
  jne S3
    ; функция смещения курсора вверх
    cmp dh,0 ; если равно нулю то не можем вверх смещать
    je SS3
      xor eax,eax      
      mov ah,2
      dec dh ; строка
      int 10h
    SS3:
  S3:
 
  cmp ax,50E0h ; \/
  jne S4
    ; функция смещения курсора вниз
    cmp dh,24 ; если равно 24 то не можем вниз смещать
    je SS4
      xor eax,eax      
      mov ah,2
      inc dh ; строка
      int 10h
    SS4:
  S4:
  
  jmp L1 ; бесконечный цикл
 
  
            
PM_CODE         ends
; ---------------------------------------------------------------------------------------------------------
 
; СЕГМЕНТ ДАННЫХ (для Protected Mode)
; ---------------------------------------------------------------------------------------------------------
PM_DATA         segment        para public 'DATA' use32
        assume         CS:PM_DATA                 
        
; сообщение, которое мы будем выводить на экран (оформим его в виде блока повторений irpc):
message:
irpc            mes,   <Hello World of PM :)>        
                db             '&mes&',0Dh
endm
mes_len         equ            $-message           ; длина в байтах
PM_DATA         ends
; ---------------------------------------------------------------------------------------------------------  
 
                end         start
3. Может в обработчик над еще какой то код добавить чтоб заработало? В реальном режиме работает.
Запускаю в DosBox. Вот что выводит(в документе Error.doc).
0
Вложения
Тип файла: doc Error.doc (40.5 Кб, 6 просмотров)
Kastaneda
Jesus loves me
Эксперт С++
5035 / 3047 / 349
Регистрация: 12.12.2009
Сообщений: 7,675
Записей в блоге: 2
Завершенные тесты: 1
28.10.2012, 17:40 5
Цитата Сообщение от ElvenDragon Посмотреть сообщение
1.А можно например 15 или 16? Или обязательно 33?
2.Можно ли на один обработчик 2 разных прерывания?
1. можно любое
2. да, хоть сколько.

Вот посмотри, вроде там есть рабочий код, который меняет позицию курсора из protected mode. Правда там на fasm, но это masm совместимый ассемблер, легко будет перевести.
1
ElvenDragon
3 / 8 / 1
Регистрация: 12.07.2009
Сообщений: 361
28.10.2012, 21:10  [ТС] 6
Цитата Сообщение от Kastaneda Посмотреть сообщение
Будет, только тебе нужно будет свой обработчик на 33 (21h) прерывание сделать.
И все же вопрос остался открытым. Допустим в дескрипторной таблице прерываний 16 дескрипторов. Я вызываю прерывание int 10h что вызывается дескриптор шлюза прерывания в таблице или прерывание которое получает курсор к примеру?
0
Kastaneda
Jesus loves me
Эксперт С++
5035 / 3047 / 349
Регистрация: 12.12.2009
Сообщений: 7,675
Записей в блоге: 2
Завершенные тесты: 1
29.10.2012, 08:32 7
Цитата Сообщение от ElvenDragon Посмотреть сообщение
Я вызываю прерывание int 10h что вызывается дескриптор шлюза прерывания в таблице или прерывание которое получает курсор к примеру?
в защищеном режиме нет больше векторов прерываний. Вместо этого есть кусок памяти, который содержит дескрипторы шлюзов прерываний. В этих же дескрипторах указан адрес обработчика. Вот какой адрес ты укажешь в 10h дескрипторе, туда и будет передано управление.
Т.е. получить позицию курсора при помощи int 10h ты уже не сможешь, если только ты не напишешь процедуру, которая получает позицию курсора, и не укажешь ее адрес в дескрипторе 10h прерывания.
1
29.10.2012, 08:32
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.10.2012, 08:32

Вывод сообщения в защищенном режиме
.386p rmcode segment para public 'CODE' use16 assume cs:rmcode,...

Перемещение файла int 21h func 56
Нужно получить аргументами командной строки путь к файлу и его новый путь, то есть либо просто...

Свободное место на диске int 21h
Программа должна выводить свободное место на введенном диске. Используется прерывание 21h функция...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru