169 похожих чатов

Добрый вечер. Есть программа резидент под DOS, которая на событие

нажатия клавиши должна выделять всю XMS память в системе (подробнее про XMS тут https://frolov-lib.ru/books/bsp.old/v33/ch11.htm)

Программа отрабатывает в эмуляторе DOSBox, в виртуалке DOS 6.22 через Virtual Box, но вот из под Qemu программа запускается, писать в клавиатуру можно, но когда нажимаешь нужную клавишу происходит зависание системы и вывод символа 'Ш' в правом верхнем углу.

Знаю, что нельзя вызывать прерывания внутри нового обработчика, но как тогда быть, подскажите что не так?

.model tiny
.code
ORG 100h
main:
jmp Init
;Ниже идет, собственно, код обработчика прерывания 09h
New_09h proc far
push ax ;сохраняем регистры
push dx
push ds
push es
mov ax,cs
mov ds,ax
mov es,ax

in al,60H ;читать ключ
cmp al,1Eh ;Если нажата клавиша 'A'
je do_pop ;да, активизировать popup

pop es ;нет, восстанавливаем регистры
pop ds
pop dx
pop ax ;и уходим на исходный обработчик

jmp cs:[Old_09h]

do_pop: ;код отработки нажатия клавиши 'A'
in al,61H ;взять значениe порта управления клавиатурой
mov ah,al ;сохранить его
or al,80h ;установить бит разрешения для клавиатуры
out 61H,al ;и вывести его в управляющий порт
xchg ah,al ;извлечь исходное значение порта
out 61H,al ;и записать его обратно
mov al,20H ;послать сигнал "конец прерывания"
out 20H,al ;контроллеру прерываний 8259

sti
mov dx,sizeMem ;перемещаем максимальное значение XMS памяти
mov ah,09h ;выделяем всю XMS память
call dword ptr HMMEntry
cli

pushf
call dword ptr cs:[Old_09h]

pop es ;восстанавливаем регистры
pop ds
pop dx
pop ax

iret ;возврат из обработчика прерываний
New_09h endp

HMMEntry DD ?
Old_09h DD 0 ;определение ячейки памяти для хранения адреса системного обработчика
sizeMem DW 0 ;переменная для хранения максимального значения XMS памяти (Кб)

;Со следующей метки нашей программы уже не будет в памяти
Init:
;Установим наш обработчик (New_09h
mov ax,3509h
int 21h mov word ptr Old_09h,bx
mov word ptr Old_09h+2,es

;запись стартового обработчика в вектор прерываний
mov ax,2509h
mov dx,offset New_09h
int 21h

;выводим сообщение о загрузке резидента в память
mov ah,09h
mov dx,offset InitMsg
int 21h

;получаем адрес управляющей функции драйвера
mov ax,4310h
int 2Fh mov word ptr HMMEntry,bx
mov word ptr HMMEntry+2,es

;определяем размер свободной расширенной памяти
mov ah,08h
xor bx,bx
call dword ptr HMMEntry
mov sizeMem,dx

;возврат в DOS, оставшись резидентным
mov dx,offset Init
int 27h

InitMsg DB "Resident installed in memory",13,10,"$"
end main

2 ответов

74 просмотра

Привет. Я не разбираюсь в єтом, просто решил сам пощупать. Не могу подтвердить поведение под Досбоксом: после вьіполнения получаю пару гудков PC-speaker'а и полную блокировку ввода с клавиатурьі. Скриншот прилагается.

Можно попробовать потестировать на реальном железе

Похожие вопросы

Обсуждают сегодня

30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
Всем привет! Имеется функция: function IsValidChar(ch: UTF8Char): Boolean; var i: Integer; ValidChars: AnsiString; begin ValidChars := 'abcdefghijklmnopqrstuvwxyzABCDE...
Евгений
44
Карта сайта