Aiwan \ (•◡•) / _bot
это все Dima виноват. помните такого? 😅
Eugene
@IvUyr, может, поставить бота на вход? Ну это маразм уже какой-то...
The Bird of Hermes
Как в досе сделать так, чтобы изменённое прерывание сохранилось для других программ? Я читал что для этого используется 27h прерывание, но у меня при его использовании крашится программа, которая вызывает изменённое прерывание
Нахуя это тут?
C17179n
Eugene
Eugene
Его нужно не только сохранить, но и передать управление по цепочке.
Можно ещё из памяти прочитать/записать (256 двойных слов-указателей, начиная с 0-го абсолютного физического адреса).
Eugene
int 27h или ah=34h (вроде, номер точно не помню, на память пишу) / int 21h делается при выходе из проги-перехватчика, чтобы DOS не удалял прогу из памяти.
Eugene
Возьми нагугли любой пример TSR-ки и посмотри. Уверен, найти её за минуту можно.
disba1ancer
The Bird of Hermes
а твоя программа к этому моменту завершалась?
Ну одна программа должна взять, заменить прерывание, завершиться. Другая программа запускается, вызывает прерывание, оно должно вызываться в изменённом виде. Замену саму я выполнил, осталось её закрепить
The Bird of Hermes
The Bird of Hermes
Что значит первый байт за резидентным участком программы в контексте прерывания? Пример, который у меня был, ставил указатель на первый байт после iret, но у меня это просто вызывает зависание
Eugene
The Bird of Hermes
Eugene
Код-то где?
Есть 2 вида обработчиков: с вызовом старого в начале/середине и с вызовом в конце.
В начале/середине:
pushf
call dword [cs:oldhandler]
...
iret ; если прерывание не возвращает флаги (типа int 21h)
В конце:
...
db 0xEA ; jmp far
oldhandler dd ?
Разумеется, не забываем, что сначала в адресе идёт слово смешения, а потом сегмента. И что все регистры нужно сохранять (в коде "..."). И что в обработчике ds != es != ss != cs.
Eugene
С некоторыми довольно сложно. Например, если нужна запись на диск, там целый квест. Нужно перехватывать int 8, int 13h, int 28h, работать с флагами типа InDOS...
Eugene
Но с 29h никаких сложностей, в принципе, не должно быть.
The Bird of Hermes
MODEL SMALL
.386
.STACK 256
.DATA
KEEP_IP DW 0
KEEP_CS DW 0
.CODE
num proc far
cmp al, 0
jl int_no_change
cmp al, 9
jg int_no_change
add al, 48
int_no_change:
int 60h
push ax
mov al, 20h
out 20h, al
pop ax
iret
finish equ '$'
num endp
MAIN:
MOV AH, 35h ;ПОЛУЧЕНИЕ ВЕКТОРА ПРЕРЫВАНИЯ
MOV AL, 29H ;НОМЕР ПРЕРЫВАНИЯ
INT 21H ;НА ВЫХОДЕ - СЕГМЕНТ В ES, СМЕЩЕНИЕ В BX
MOV KEEP_IP, BX
MOV KEEP_CS, ES
CLI ;ЗАПРЕТ ПРЕРЫВАНИЙ
PUSH DS
MOV DX, KEEP_IP
MOV AX, KEEP_CS
MOV DS, AX
MOV AH, 25h
MOV AL, 60h
INT 21h
lea dx, num
mov ax, seg num
mov ds, ax
mov ah, 25h ;установить вектор прерывания
mov al, 29h ;номер прерывания, вектор которого требуется установить
int 21h
POP DS
STI ;РАЗРЕШЕНИЕ ПРЕРЫВАНИЙ
mov al, 7 ;ПРОВЕРКА РАБОТЫ
int 29h
mov dx, offset(finish)
int 27h
END MAIN
The Bird of Hermes
В рамках этой программы замена работает полностью правильно, а вот вызов прерывания из другой после завершения работы этой вызывает повисание
Eugene
out 20h,al тут не нужен - это не аппаратное прерывание.
С int 60h, конечно, оригинально, но лучше как я написал, классика.
Сегмент данных не инициализирован в main.
cli/sti тут лишние, зачем?
int 27h используется в COM-программах, а не в EXE.
Вообще, сделай COM лучше.
Eugene
finish equ '$' - лол, зачем тут кавычки-то? 😁
The Bird of Hermes
The Bird of Hermes
Других не нашёл
Eugene
Странный учебник.
Eugene
Цифра 7 хоть выводится?
The Bird of Hermes
Всё равно ни то ни другое не помогло. А комовские файлы там как делать?
The Bird of Hermes
И возврат управления происходит
The Bird of Hermes
А при вызове из другой программы вывода нет, возврата управления нет, просто мигает курсор
Eugene
The Bird of Hermes
The Bird of Hermes
Ну символ семерка
The Bird of Hermes
Я ж не дурак
The Bird of Hermes
Знаю как оно должно работать
Eugene
Потому что надо ah=31h/int21h использовать.
И ds проинициализаруй.
The Bird of Hermes
Eugene
COM: https://frolov-lib.ru/books/bsp.old/v01a/ch5.htm
Eugene
RBIL online найди.
Eugene
Вот лучше:
http://www.ctyme.com/rbrown.htm
Eugene
http://www.ctyme.com/intr/rb-2723.htm
Eugene
Но это надо относительно начала PSP :)
Eugene
Сделай ком и не мучайся.
Eugene
https://pascal.sources.ru/asm/faq/index.htm#tsr
Eugene
Вот нашёл из старого фака.
s54820
The Bird of Hermes
mov ax, seg num
Эта строчка вызывает эту ошибку
The Bird of Hermes
s54820
У тебя один сегмент в .com, он при старте уже лежит в ds. Перед установкой вектора 60h ты его сохраняешь, восстанови потом и всё.
The Bird of Hermes
Всё работает, всем спасибо
The Bird of Hermes
Как работают команды offset и Lea? Откуда они берут адрес/вычисляют его?
Eugene
Какой адрес указываешь, тот и берётся.
The Bird of Hermes
The Bird of Hermes
приведи примеры, так проще объяснить
Ну вот смотри, я пишу команду
Lea dx, переменная
Как он определяет её смещение? В теории это должно помочь понять, где заканчивается одна переменная и начинается другая, допустим, при определении длины массива
Aiwan \ (•◡•) / _bot
Aiwan \ (•◡•) / _bot
Aiwan \ (•◡•) / _bot
The Bird of Hermes
The Bird of Hermes
The Bird of Hermes
Чтобы туда поставить
Aiwan \ (•◡•) / _bot
А откуда он его берёт?
вот чем корень проблем. тогда изучи формат PE. там есть такие понятия как база секции итд. вот оттуда и вычисляет
Aiwan \ (•◡•) / _bot
секция данных допустим 401000. твоя метка указывает на второй dword в этой секции. получаем 401000+4=401004 - адрес метки при выполнении программы. (все в хексах)
The Bird of Hermes
The Bird of Hermes
The Bird of Hermes
Я же не буду каждую метку по очереди брать, тогда мне это бессмысленно будет
The Bird of Hermes
Именно все адреса скопом
Aiwan \ (•◡•) / _bot
Aiwan \ (•◡•) / _bot
The Bird of Hermes
тогда делай массив меток
Ну он же как-то хранит, первый дворд, второй дворд и т.д. Я могу получить доступ к адресу не по названию, а по номеру?
The Bird of Hermes
смысл?
Перебрать адреса, найти ближайший к нужному мне, следующий после него, определить размерность соответственно.