Форум программистов, компьютерный форум, киберфорум
Assembler: DOS/Real Mode/16-bits
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
 Аватар для ElvenDragon
3 / 8 / 1
Регистрация: 12.07.2009
Сообщений: 361

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

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

Студворк — интернет-сервис помощи студентам
Будет ли прерывание int 21h функции ah=9 вывода строки работать в защищенном режиме?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.10.2012, 10:43
Ответы с готовыми решениями:

Вывод строки на экран. Прерывание 21H функция 09H
Нужно просто вывести строку на экран string1 db 'Введите последовательность символов','$' ...

Прерывание 21h - при чтении из файла выводятся лишние символы
Здравствуйте. По заданию программа должна открывать файл на чтение, считывать информацию и закрывать файл. Реализовать всё нужно...

Будет ли такая сборка работать в двухканальном режиме
Я хочу добавить 2 планки Hynix DDR3 1333 DIMM 4Gb к своим 2 Kingston KVR1333D3N9/2G, будет ли работать в двухканальном режиме? Железо ...

6
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
28.10.2012, 15:05
Будет, только тебе нужно будет свой обработчик на 33 (21h) прерывание сделать.
0
Клюг
 Аватар для Charles Kludge
7677 / 3192 / 382
Регистрация: 03.05.2011
Сообщений: 8,380
28.10.2012, 15:12
Под DPMI - да. https://www.cyberforum.ru/post2784506.html
0
 Аватар для ElvenDragon
3 / 8 / 1
Регистрация: 12.07.2009
Сообщений: 361
28.10.2012, 17:02  [ТС]
Цитата Сообщение от 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).
Вложения
Тип файла: doc Error.doc (40.5 Кб, 6 просмотров)
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
28.10.2012, 17:40
Цитата Сообщение от 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  [ТС]
Цитата Сообщение от Kastaneda Посмотреть сообщение
Будет, только тебе нужно будет свой обработчик на 33 (21h) прерывание сделать.
И все же вопрос остался открытым. Допустим в дескрипторной таблице прерываний 16 дескрипторов. Я вызываю прерывание int 10h что вызывается дескриптор шлюза прерывания в таблице или прерывание которое получает курсор к примеру?
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
29.10.2012, 08:32
Цитата Сообщение от ElvenDragon Посмотреть сообщение
Я вызываю прерывание int 10h что вызывается дескриптор шлюза прерывания в таблице или прерывание которое получает курсор к примеру?
в защищеном режиме нет больше векторов прерываний. Вместо этого есть кусок памяти, который содержит дескрипторы шлюзов прерываний. В этих же дескрипторах указан адрес обработчика. Вот какой адрес ты укажешь в 10h дескрипторе, туда и будет передано управление.
Т.е. получить позицию курсора при помощи int 10h ты уже не сможешь, если только ты не напишешь процедуру, которая получает позицию курсора, и не укажешь ее адрес в дескрипторе 10h прерывания.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
29.10.2012, 08:32
Помогаю со студенческими работами здесь

Найдите вероятность того, что автобаза будет работать в нормальном режиме
Модель повторных испытаний схеме Бернулли. Теоремы Муавра-Лапласа И Пуассона. Образующая Функция ...

Перехват int 21h
Добрый день. Заменяю обработчик 21-ого прерывания на свое, где я вызываю старый обработчик, однако... Мое &quot;Hi!&quot; он не выводит...

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

Перехват int 21h
Подскажите пожалуйста. Как передать управление оригинальному обработчику 21h? CSEG Segment ASSUME CS:CSEG org 100h begin: ...

Действие int 21h
ааа ну вроде я понял вниз кароч отсчитываем пока не будет делимое число и количество отсчитываний и будет твой остаток? число 150 /2 =7,1...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! в-строка - входное арифметическое выражение в инфиксной(обычной). . .
Камера 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, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru