Форум программистов, компьютерный форум, киберфорум
Assembler: DOS/Real Mode/16-bits
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.98/63: Рейтинг темы: голосов - 63, средняя оценка - 4.98
1 / 1 / 0
Регистрация: 08.07.2011
Сообщений: 50
TASM

Обработчик прерывания int 21h (по книге Калашникова)

13.07.2011, 04:03. Показов 12577. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброе время суток, я чтиаю книгу Калашникова-Ассемблер и уже втрой день не могу понять почему обработчик не перехватывает прерывания и не меняет строку,листинг перехвата 21го прерывания:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
CSEG segment
 org 100h
  Start:
   ;Переходим на метку инициаллизации. Нам нужно будет перехватить прерывание int 21h, а также оставить программу резидентной в памяти
   
   jmp Init
   
   ; Ниже идет код обработки прерывания 21h (он будет резидентный) .После того ,как процедура выйдет , процедура int_21h_proc останется в памяти и будет контроллировать функцию 09 прерывания 21h.
   
   int_21h_proc proc
   cmp ah,9   ;проверим , это функция 09h ?
   je Ok_09
   
   ; Если нет , перейдем  на оригинальный обработчик 21h. На метку Ok_09 программа уже не вернется
   
   jmp dword ptr cs:[int_21h_vect]
   
   Ok_09:
   push ds; сохраняем регистры
   push dx;
   push cs; Адрес строки должен быть в ds:dx
   pop ds
   
   ;выводим нашу строку (my_string), вмето той, которую должна была вывести программа, вызывающая 21h- прерывание
   
   mov dx,offset my_string
   pushf; эта инструкция здесь необходима
   call dword ptr cs:[int_21h_vect] 
   
   pop dx; Восстановим используемые регистры
   pop ds
   iret; продолжим работу, выйдем из  прерывания
   ;программа ,выводящая строку, считает , что на экране было выведено ее сообщение. Но на самом деле это не так
   
   ;переменная для хранения оригинального обработчика 21h
   int_21h_vect dd ?
   
   my_string db ' Perehvat !$'
   int_21h_proc endp
   
   ;Со следующей метки нашей программы уже не будет в памяти (это нерезидентная часть).
   ; она затрется после выхода(после прерывания 27h)
   
   Init:
   ; установим наш обработчик (int_21h_proc) (адрес нашего обработчика) на прерывние 21h
   ;Но прежде нужно запомнить оригинальный адрес этого прерывания . Для этого используется функция 35h прерывания 21h:
   
   ; ah содержит номер функции
   mov ah,35h ; получаем оригинал
   ;al указывает номер прерывания, адрес (вектор) ,которого нужно получить
   
   mov al,21h
   int 21h
   ;теперь в es:bx адрес (вектор) прерывания 21h (es - сегмент bs-смещение):
   
   mov word ptr int_21h_vect,bx; сохраняем в переменную
   mov word ptr int_21h_vect+2,es
   
   ;адрес сохранили, теперь обрабатываем прерывание:
   mov ax,2521h
   mov dx,offset int_21h_proc ;ds:dx  должны указывать на наш обработчик (т.е int_21h_proc)
   int 21h
   
   ;Теперь если какая-то программа вызовет int 21h, то вначале компъютер попадает на обработчик int_21h_proc.
   ;Осталось завершить программу. оставив ее резидентной в памяти (чтобы никто не затер разработчик, иначе комп висанет)
   
   mov dx,offset Init
   int 27h
   
   ;Прерывание int 27h выходит в ДОС (как 20h) , при этом оставив нашу программу резидентной,
   ;dx должен указывать на последний байт, оставшийся в памяти (это как раз метка Init).То есть в памяти
   ;остается от 000h до адреса по которому метка Init
   
   CSEG ends
   end Start
Файл, на котором тестирую:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CSEG segment
assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
org 100h
 
Begin:
    mov ah,9
    mov dx,offset String
    int 21h
         mov ax,10h
         int 16h
    int 20h
 
String db 'Stroka.$'  ;Пробуем вывести это строку
 
CSEG ends
end Begin
Листинг перехвата 10го прерывания
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
CSEG segment
assume cs:CSEG, ds:CSEG, ss:CSEG, es:CSEG
org 100h
 
Begin:
       jmp Init ;На метку инициализации 
 
 
; === Процедура обработки 10h прерывания ===
Int_10h_proc proc
      pushf ;Сохраним флаги в стеке, т.к. они поменяются...
 
      cmp ax,8899h  ;Проверим на повторную загрузку в память (см. ниже)
      jne Next_test ;Если не проверка, то смотрим дальше... 
 
      xchg ah,al    ;Меняем местами AH и AL (признак того, что мы в памяти
            ;что-то вроде ответного сигнала)
      popf  ;Выровним стек
      iret  ;Выйдем из прерывания (вернемся в нашу программу)
            ;AX теперь равен 9988h !!!
 
Next_test:
      cmp ah,88h    ;Это вызов нашей функции?
      jne Go_10h    ;Если нет - уйдем в оригинальный обработчик 10h 
 
      push es       ;Сохраним ES...
 
      mov ax,0B800h ;...и занесем в него сегмент 0-ой страницы дисплея
      mov es,ax
 
      xor di,di     ;Подготвимся к чистке экрана (равносильно mov di,0)
      mov cx,2000   ;Просто "забьем" его пробелами.
      mov ax,0720h  ;Будем заносить: код цвета (07) / символ пробела (20h)
      rep stosw     ;"Забиваем"... Очень быстро...
 
      mov di,1014   ;Будем выводить вот отсюда (примерно центр экрана)
      mov ah,14     ;С такими атрибутами (светло-желтый)
 
Next_sym:
      lodsb     ;Заносим в AL очередной символ (один байт, т.к. lodsB),
            ;Расположенный по адресу DS:SI, увеличив затем SI
            ;на единицу
 
      cmp al,0      ;Конец строки?
      jz Stop_out   ;Да - на выход... 
 
      stosw ;Заносим по адресу ES:DI значение из AX и увеличиваем DI на 2
        ;Здесь заносим слово, т.к. stosW, поэтому на два и
        ;увеличивается значение DI
 
      jmp short Next_sym ;Следующий символ... 
             ;SHORT (короткий) - делает в некоторых случаях
             ;команду jmp на один байт короче.
             ;Работает ТОЛЬКО в том случае, если между меткой
             ;и jmp расстояние не более 127 байт!
 
Stop_out:
      pop es    ;Если достигли конца строки, то восстановим регистры,
      popf  ;выровнив стек...
      iret  ;...и выйдем из прерывания
 
Go_10h:
      popf  ;Выровним стек
      jmp dword ptr cs:[Int_10h_vect]   ;"Прыгаем" на оригинальный обработчик
 
Int_10h_vect dd ? ;Здесь хранится адрес оргинального обработчика
Int_10h_proc endp
 
 
; ===============================================================
; Инициализация (подготовка и настройка резидента)
Init:
       mov ax,8899h ;Проверим, в памяти ли мы уже или еще нет
       int 10h      ;8899h - наш позывной
       cmp ax,9988h ;Отозвался обработчик (AH/AL должены поменяться местами)?
       jne Set_resident
 
       mov ah,9     ;Если в памяти, то выведем соответствующее сообщение
       mov dx,offset In_memory ;Зачем нас двое в памяти?
       int 21h
 
       ret      ;...И вернемся в DOS
 
 
Set_resident:       ;Если нас в памяти нет, то установим резидент
       mov ax,3510h
     int 21h        
[B]; Зачем здесь 21 прерывание ,если идет перехвыт 10го , или ф-я 35h неотъемлема от прерывния 21h для перехвата?[/B]
 
;Получим и сохраним адрес (вектор) 10h прерывания
       mov word ptr Int_10h_vect,bx ;Вначале младшее слово (смещение)
       mov word ptr Int_10h_vect+2,es   ;Затем старшее (сегмент)
 
       mov ax,2510h
       mov dx,offset Int_10h_proc
       int 21h      ;"Повесим" нашу процедуру на 10h прерывание
 
       mov dx,offset Init
       int 27h      ;Оставим программу резидентной в памяти.
 
In_memory db 'Мы уже в памяти!!!!$'
 
CSEG ends
end Begin
Да, и если считаете,что данная книга тяжелая для первого ознакомления, посоветуйте пожалуйста какую-то другую, желательно, в которой речь шла бы о системном программировании и о создании антивирусов и вирусов на языке ассемблер.
Спасибо за внимание,если что не так написал, извините,на данном форуме впервые и с ассемблером стаклкиваюсь впервые, а вещь очень нужная

Добавлено через 43 минуты
Да, и зачем в листинге call dword ptr cs:[int_21h_vect] , jmp dword ptr cs:[int_21h_vect],что оно означает, ведь такой процедуры нет, или это ссылка на переменную, в которой хранится адрес 21го прерывания.К сожалению , в учебнике не объясняются все вещи сразу.

Добавлено через 2 минуты
Да, и зачем в листинге 1 call dword ptr cs:[int_21h_vect] , jmp dword ptr cs:[int_21h_vect],что оно означает, ведь такой процедуры нет, или это ссылка на переменную, в которой хранится адрес 21го прерывания.К сожалению , в учебнике не объясняются все вещи сразу.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
13.07.2011, 04:03
Ответы с готовыми решениями:

Резидентный обработчик прерывания 21h (по книге Калашникова)
Всем добрый день. Изучаю ассемблер по книге Калашникова . Программа перехватывает 21-ое прерывание и подменивает выводимую строку. ...

Резидентный обработчик 21h прерывания (из 10-й главы Калашникова)
Имеется вот такой код резидентного обработчика прерываний, написанный предположительно на MASM данная программа должна после выполнения...

Перехват прерывания int 21h
Немного решил поэкспериментировать. Есть два случая для сравнения. Первый случай (работает): CSEG segment assume cs:CSEG,...

17
 Аватар для zzzyyyxxx
768 / 312 / 11
Регистрация: 27.05.2011
Сообщений: 703
13.07.2011, 06:58
пример перехвата 21го прерывания рабочий и файл для тестирования тоже,
единственный момент,

в перехвате допиши это - [2. assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG]

и bat файл такой:
c:\tasm\bin\tasm prog.asm
c:\tasm\bin\tlink /t prog.obj
pause
0
1 / 1 / 0
Регистрация: 08.07.2011
Сообщений: 50
13.07.2011, 19:27  [ТС]
Странно, но у меня почему-то выводится исходная строка из теста, а не строка из перехвата
0
 Аватар для zzzyyyxxx
768 / 312 / 11
Регистрация: 27.05.2011
Сообщений: 703
13.07.2011, 21:49
Зайди в пуск->выполнить->cmd.
После запуска, пропиши путь к перехватчику.
Далее укажи путь, к тест-файлу и ВСЁ.

P.S.: Для того, чтобы не возиться с путями, скинь оба файла в корень диска
0
1 / 1 / 0
Регистрация: 08.07.2011
Сообщений: 50
14.07.2011, 00:45  [ТС]
Да,прописывал
C:\Assembler\MASM611\BIN\ML.EXE PROG10.ASM /AT
C:\Assembler\MASM611\BIN\ML.EXE Test10.ASM /AT
Сгенерировались com-файлы и ни фига, не перехватывает
0
 Аватар для zzzyyyxxx
768 / 312 / 11
Регистрация: 27.05.2011
Сообщений: 703
14.07.2011, 07:55
ну так бы сразу написал бы, что используешь MASM.
с MASM в DOS я не работал, так что чё к чему не знаю, использую его тока для WIN,
если это не принципиально, то вот TASM:
Вложения
Тип файла: rar TASM.rar (162.9 Кб, 102 просмотров)
2
 Аватар для Goodwin98
2537 / 833 / 10
Регистрация: 31.05.2009
Сообщений: 1,668
14.07.2011, 13:42
Tetr1s, вы как тестируете ?
0
1 / 1 / 0
Регистрация: 08.07.2011
Сообщений: 50
15.07.2011, 03:44  [ТС]
Спасибо, через TASM все работает
0
1 / 1 / 0
Регистрация: 08.07.2011
Сообщений: 50
16.07.2011, 05:06  [ТС]
Прошу прощение, я немного ошибся в названиях файлов при тестировании через TASM, через TASM тоже не перехватывает,тестирую так:
Пуск->Выполнить->
c:\Assembler\TASM\tasm prog10.asm
c:\Assembler\TASM\tlink /t prog10.obj
запускаю сгенерированный .com файл
потом гененрирую
c:\Assembler\TASM\tasm test10.asm
c:\Assembler\TASM\tlink /t test10.obj
запускаю сгенерированный .com файл
и выводится исходная строка
0
 Аватар для Goodwin98
2537 / 833 / 10
Регистрация: 31.05.2009
Сообщений: 1,668
16.07.2011, 13:26
Ну а как вы "запускаете сгенерированный .com файл" ?
0
1 / 1 / 0
Регистрация: 08.07.2011
Сообщений: 50
18.07.2011, 01:14  [ТС]
Двойным кликом по .com файлу
0
 Аватар для Goodwin98
2537 / 833 / 10
Регистрация: 31.05.2009
Сообщений: 1,668
18.07.2011, 05:02
А почему все это не в cmd, как вам посоветовали выше ?
1
1 / 1 / 0
Регистрация: 08.07.2011
Сообщений: 50
19.07.2011, 02:13  [ТС]
Спасибо,заработало, а не подскажите, почему через клики не работало?
и какой учебник по ассемблеру сгодится для первого ознакомления, может мне еще рано читать Калашникова??Может начать с классического для ВУЗов,такого, как Юров?Так как с ассеммблером с первого курса не сталкивался,и тогда не особо понимал зачем он нужен,потребность а нем возникла после изучения языков высокого уровня.
0
 Аватар для Goodwin98
2537 / 833 / 10
Регистрация: 31.05.2009
Сообщений: 1,668
19.07.2011, 04:50
Цитата Сообщение от Tetr1s Посмотреть сообщение
почему через клики не работало?
Потому что при запуске каждый раз создавалась новая виртуальная машина с досом, а после запуска cmd все происходило внутри одной машины.
0
1 / 1 / 0
Регистрация: 08.07.2011
Сообщений: 50
19.07.2011, 04:54  [ТС]
спасибо
0
procamist
05.11.2012, 11:11
Вопрос по первому обработчику прерываний
Assembler
1
2
3
4
5
6
7
 ...
   push ds; сохраняем регистры
   push dx;
   push cs; Адрес строки должен быть в ds:dx
   pop ds
   mov dx,offset my_string
...
Вот тут почему мы в ds заносим cs? мне казалось что cs указывает на сегмент кода программы которая вызвала прерывание. Следовательно получается теперь НАША строка будет находится в сегменте кода вызывающей программы со смещением как в обработчике?
 Аватар для Goodwin98
2537 / 833 / 10
Регистрация: 31.05.2009
Сообщений: 1,668
05.11.2012, 12:05
Тут весь код в одном сегменте.
0
procamist
05.11.2012, 13:48
При запуске программы-теста , обработчик находится в одном сегменте, а программа в другом? если так то получается что в

обработчике адрес ds:dx будет указывать на сегмент кода программы, а смещение на строку в обработчике... вроде так..


и еще вопрос про
jmp dword ptr cs:[int_21h_vect]

в коде вот таком

...
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CSEG segment
org 100h
Begin:
        
mov ax,3         
int 10h     
 
mov ax,0B800h
mov es,ax   
mov di,0
mov al,1
mov ah,31
mov es:[di],ax
        
mov ah,10h  
int 16h
    
int 20h
 
CSEG ends
end Begin
...

Здесь mov es:[di],ax мы заносим значение ax по адресу, а di - это вроде смещение, но тут
jmp dword ptr cs:[int_21h_vect]

[int_21h_vect] - 4 байтная переменная содержащая и смещение и сегмент, то есть мы прыгаем по смещение:[смещение сегмент]
это как?
и зачем тут dword ptr?
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
05.11.2012, 13:48
Помогаю со студенческими работами здесь

Резидентная программа - перехват прерывания int 21h ah=09h
Задание: перекрыть 9 функцию 21 прерывания в assembler. Помогите, плиз, разобраться как правильно ставить перекрывание. Решил с самого...

Почему при вызове функции 4ch прерывания 21h резидентный обработчик падает?
Написал резидентную программу, всё работает, но если моя или другие программы вызывают функцию 4ch прерывания 21h, консоль перестаёт...

Резидент: Вывод таблицы векторов прерывания не используя int 21H
Нужно вывести на экран Ms DOs таблицу векторов прерывания НЕ используя int 21H! так что я предполагаю через int 10H.. уже неделю с этим...

Перехват прерывания int 21h ah=0Ah: во вводимой строке продублировать все гласные буквы
Привет всем, задали тут задачку: -Переопределить десятую функцию прерывания 21h таким образом, чтобы в вводимой строке были...

Вывод на экран сообщения функцией 9Н прерывания INT 21H
Определите данные и напишите команды, необходимые для вывода на экран функцией 9Н прерывания INT 21H сообщения “What is the current date...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru