Вопрос № 108890: Написал резидент который создает файл при обращении к 21h (вывод строки на экран) прерыванию и что-то он не работает подскажите в чем дело. И почему при востановлении из стека регистров CX и AX на метке B12 значение регистра CX пропадает и данные (09...
Вопрос № 108.890
Написал резидент который создает файл при обращении к 21h (вывод строки на экран) прерыванию и что-то он не работает подскажите в чем дело. И почему при востановлении из стека регистров CX и AX на метке B12 значение регистра CX пропадает и данные (09h) предназначенные для регистра AX попадают в CX.
Да, в одной из ваших рассылок видел, чтобы программу оставить резидентно необходимо вополнить 27h прерывание. Какой вариант лучше? Буду благодарен если пришлете правильный код программы, а то мучаюсь уже который день. Спасибо.
Отвечает: Зенченко Константин Николаевич
Здравствуйте, Каликов Сергей Александрович!
По не резидентной части:
mov ah,31h
LEA dx, init
int 21h
Эта функия резервирует объем памяти указанный в параграфах. Параграф - 16-ти байтная область памяти
При компиляции Вашей программы компилятор записывает число 012Bh=299 т.е. резервируемая область памяти равна 4784(299*16) байта, при необходимых 299 байтах .
В Вашем случае выгодно использовать:
LEA dx, init
int 27h
вместо дополнительных вычислений:
mov ah,31h
LEA dx, init shr dx,4
inc dx
int 21h
По резидентной части:
a10:
cmp ah,9
jne exit
;сохраняем все используемые регистры
pusha
;на момент вызова обработчика достоверно известен только CS
;DS - не известен, по этому его и определяем DS=CS, для функции 3Ch
;т.к. для открытия(создания) имя файла должно указыватся парой DS:DX
push ds
push cs
pop ds
mov ah,3ch
mov cx,00
lea dx,fil;У Вас обработчик будет пытатся открыть файл с именем
;по адресу DS:DX=??:103h, а там может быть и код вместо имени
pushf;возврат будет по IRET-это 3-и байта(flag, CS:IP)
CALL DWORD PTR cs:[saveint9]
;закрываем открытый файл
;т.к. при повторном открытии (уже открытого файла)может появится ошибка
;выполнения функции, которая Вами не учитывается.
mov bx,ax
mov ah,3eh
pushf;
CALL DWORD PTR cs:[saveint9]
pop ds;востанавливаем все регистры
popa
;в принципе тут можно вернутся по IRET
;если не нужно выводить строку
exit:
jmp cs:[saveint9]
Приблизительно так я бы написал такой обработчик.
ps: Для использования команд : pusha | pushf | popa | shr dx,4
поставте в начале программы директиву: .186- разрешить команды 186-го процессора
Удачи!
--------- И только наступив на грабли мы приобретаем драгоценный опыт!