Aiwan \ (•◡•) / _bot
это все Dima виноват. помните такого? 😅
Eugene
@IvUyr, может, поставить бота на вход? Ну это маразм уже какой-то...
The Bird of Hermes
Как в досе сделать так, чтобы изменённое прерывание сохранилось для других программ? Я читал что для этого используется 27h прерывание, но у меня при его использовании крашится программа, которая вызывает изменённое прерывание
­
Нахуя это тут?
C17179n
Eugene
Его нужно не только сохранить, но и передать управление по цепочке. Можно ещё из памяти прочитать/записать (256 двойных слов-указателей, начиная с 0-го абсолютного физического адреса).
The Bird of Hermes
ah=35h / int 21h получает старый обработчик, ah=25h устанавливает новый.
Это я знаю, вопрос в том, как после завершения программы в других программах прерывание при вызове выполняло то, что в него записалось в этой. Я пытался использовать 27h для этого, но при попытке вызова изменённого прерывания всё висло
Eugene
int 27h или ah=34h (вроде, номер точно не помню, на память пишу) / int 21h делается при выходе из проги-перехватчика, чтобы DOS не удалял прогу из памяти.
Eugene
Возьми нагугли любой пример TSR-ки и посмотри. Уверен, найти её за минуту можно.
The Bird of Hermes
а твоя программа к этому моменту завершалась?
Ну одна программа должна взять, заменить прерывание, завершиться. Другая программа запускается, вызывает прерывание, оно должно вызываться в изменённом виде. Замену саму я выполнил, осталось её закрепить
The Bird of Hermes
int 27h или ah=34h (вроде, номер точно не помню, на память пишу) / int 21h делается при выходе из проги-перехватчика, чтобы DOS не удалял прогу из памяти.
27h прерывание или 31h функция 21h прерывания, да. Вопрос в том, как заставить хоть одно из этого работать, описаний полно, а рабочего примера не особо
The Bird of Hermes
Что значит первый байт за резидентным участком программы в контексте прерывания? Пример, который у меня был, ставил указатель на первый байт после iret, но у меня это просто вызывает зависание
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
finish equ '$' - лол, зачем тут кавычки-то? 😁
Я делал по примеру из учебника
The Bird of Hermes
Других не нашёл
Eugene
Странный учебник.
Eugene
Цифра 7 хоть выводится?
The Bird of Hermes
Всё равно ни то ни другое не помогло. А комовские файлы там как делать?
The Bird of Hermes
Цифра 7 хоть выводится?
Как выводилась, так и выводится
The Bird of Hermes
И возврат управления происходит
The Bird of Hermes
А при вызове из другой программы вывода нет, возврата управления нет, просто мигает курсор
The Bird of Hermes
Ну символ семерка
The Bird of Hermes
Я ж не дурак
The Bird of Hermes
Знаю как оно должно работать
Eugene
Потому что надо ah=31h/int21h использовать. И ds проинициализаруй.
Eugene
COM: https://frolov-lib.ru/books/bsp.old/v01a/ch5.htm
Eugene
А на вход ей что подавать?
Посмотри справочник, я не помню.
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
Вот нашёл из старого фака.
The Bird of Hermes
Сделай ком и не мучайся.
Segment-relocatable items present in module
The Bird of Hermes
model tiny
Её и использую
The Bird of Hermes
mov ax, seg num Эта строчка вызывает эту ошибку
s54820
mov ax, seg num Эта строчка вызывает эту ошибку
А, так выкинь это. Там у тебя ниже есть pop ds, просто перетащи его как раз вместо этой строчки и следующей.
s54820
У тебя один сегмент в .com, он при старте уже лежит в ds. Перед установкой вектора 60h ты его сохраняешь, восстанови потом и всё.
The Bird of Hermes
Всё работает, всем спасибо
The Bird of Hermes
Как работают команды offset и Lea? Откуда они берут адрес/вычисляют его?
Eugene
Какой адрес указываешь, тот и берётся.
The Bird of Hermes
Какой адрес указываешь, тот и берётся.
Откуда он берётся, как вычисляется?
Aiwan \ (•◡•) / _bot
Откуда он берётся, как вычисляется?
приведи примеры, так проще объяснить
The Bird of Hermes
приведи примеры, так проще объяснить
Ну вот смотри, я пишу команду Lea dx, переменная Как он определяет её смещение? В теории это должно помочь понять, где заканчивается одна переменная и начинается другая, допустим, при определении длины массива
The Bird of Hermes
давай из реального кода. у тя так с ошибками получается
Да мне бы понять сам принцип. Вот смотри, мы определяем длину массива обычно так: (Смещение переменной после массива - смещение массива) / тип данных, так?
The Bird of Hermes
и чтоб это понять/разобраться перепрограммируй мозг на то, что в асме нет переменных. есть адреса и данные по этим адресам
Ну смотри, переменная это что? Это метка. Мне надо определять, принадлежит ли данный байт какой-либо метке, вообще любой
Aiwan \ (•◡•) / _bot
Ну смотри, переменная это что? Это метка. Мне надо определять, принадлежит ли данный байт какой-либо метке, вообще любой
"метка" это понятие для исходника, для сомого ассемблера/компиля/транслятора. вместо метки асм вставляет адрес
The Bird of Hermes
Чтобы туда поставить
Aiwan \ (•◡•) / _bot
А откуда он его берёт?
вот чем корень проблем. тогда изучи формат PE. там есть такие понятия как база секции итд. вот оттуда и вычисляет
Aiwan \ (•◡•) / _bot
секция данных допустим 401000. твоя метка указывает на второй dword в этой секции. получаем 401000+4=401004 - адрес метки при выполнении программы. (все в хексах)
Aiwan \ (•◡•) / _bot
Так, а это уже интересно. Я могу как-то получить адреса вообще всех переменных из секции?
да, для этого придумали метки, асм сам подставляет вместо них в итоговую программу адреса
The Bird of Hermes
The Bird of Hermes
Я же не буду каждую метку по очереди брать, тогда мне это бессмысленно будет
The Bird of Hermes
Именно все адреса скопом
The Bird of Hermes
тогда делай массив меток
Ну он же как-то хранит, первый дворд, второй дворд и т.д. Я могу получить доступ к адресу не по названию, а по номеру?
The Bird of Hermes
смысл?
Перебрать адреса, найти ближайший к нужному мне, следующий после него, определить размерность соответственно.
Aiwan \ (•◡•) / _bot
Перебрать адреса, найти ближайший к нужному мне, следующий после него, определить размерность соответственно.
так поставь метку my_end_data: в конце секции данных, и будет тебе размер данных в байтах если вычесть адрес аначала секции. или сразу посчитай при компиляции size_data = $ - first_data