EMu 8086 и int27h - несовместимы?

Низкоуровневое программирование портов, микроконтроллеров и т.д.

Модератор: Andy

Ответить
Jezrien
Сообщения: 1
Зарегистрирован: 01 июн 2017, 09:10

01 июн 2017, 09:14

Доброе утро. Ребят, есть резидентная программа, захватывающая некоторый участок экрана, и записывает его в файл. При выполнении на emu8086, ругается на int27h. Подскажите в чем проблема, почему не работает ?

Код: Выделить всё

CSEG segment
assume cs:CSEG, ds:CSEG, ss:CSEG, es:CSEG
org 100h
Begin:
jmp Init ;На метку инициализации
; Инициализация (подготовка и настройка резидента)
Init:
mov ax,3509h
int 21h ;Получим и сохраним адрес (вектор) 21h прерывания
mov word ptr Int_09h_vect,bx ;Вначале младшее слово (смещение)
mov word ptr Int_09h_vect+2,es ;Затем старшее (сегмент)
mov ax,2509h ;устанавливаем вектор прерывания
mov dx,offset Int_09h_proc
int 21h ;"Повесим" нашу процедуру на 09h прерывание
mov dx,offset Init
int 27h ;Оставим программу резидентной в памяти.
In_memory db 'Мы уже в памяти!!!!$'
Int_09h_proc proc
pushf ; сохраним флаги и регистры
push ax
push bx
push cx
push dx
push es
push ds
in al, 60h ; читать кнопку
cmp al, 42h ; это F5?
jne go_09h ; если нет - на оригинальный обработчик
in al, 61h ; взять значение порта управления клавиатурой
mov ah, al ; сохранить его
or al, 80h ; установить бит разрешения для клавиатуры
out 61h, al ; и вывести его в управляющий порт
xchg ah, al ; извлечь исходное значение порта
out 61h, al ; и записать его обратно
mov al, 20h ; послать сигнал "конец прерывания
out 20h, al ; контроллеру прерываний 8259
mov ax, 0b800h ; в ax - начальный адрес видеопамяти для текстовых режимов
mov es, ax ; оттуда в es, напрямую с es работать нельзя
xor di, di ; обнуляем di
mov si, offset logfile ; в si - адрес массива, в который будем писать символы с экрана
wr: ; начало цикла записи
movsb ; записать данные из ячейки es:[di] в ячейку ds:[si]
inc si ; si++
inc di ; di++
cmp si, 0b800h ; еще не конец массива?
jne wr ; тогда в цикл
mov ah, 3ch ; создание файла
mov cx, 0 ; атрибут файла - доступен для чтения/записи
mov dx, offset filename ; в dx - адрес переменной, в которой лежит имя файла
int 21h ; прерывание
mov bx, ax ; описатель файла сохраним в bx, потом понадобится
mov cx, 0 ; в cx - смещение указателя
mov dx, 0 ; в dx - база указателя
mov al, 2 ; атрибуты открытия файла
mov ah, 42h ; установка указателя для записи в файл
int 21h ; прерывание
mov ah, 40h ; запись в файл
mov dx, offset logfile ; в dx - адрес массива данных, который будем записывать
mov cx, 0b800h ; в cx - объем записяваемых данных
int 21h ; прерывание
mov ah, 3eh ; закрытие файла
int 21h ; прерывание
Go_09h:
pop ds ; восстановим регистры
pop es ;
pop ds ;
pop cx ;
pop bx ;
pop ax ;
popf ;Выровняем стек
jmp dword ptr cs:[Int_09h_vect] ;"Прыгаем" на оригинальный обработчик
iret
Int_09h_vect dd ? ;Здесь хранится адрес оргинального обработчика
filename db 'res.txt', 0 ; имя файла, если не указан путь - создается в директории исполняемого файла
logfile db 0b800h dup (0) ; массив данных для записи
Int_09h_proc endp
CSEG ends
end Begin
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

03 июн 2017, 09:48

Это прерывание зарезервировано эмулятором. Используйте функцию 31h прерывания INT 21h
It's a long way to the top if you wanna rock'n'roll
Ответить