Форум программистов, компьютерный форум, киберфорум
Наши страницы
Assembler, MASM, TASM
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.77/22: Рейтинг темы: голосов - 22, средняя оценка - 4.77
Go.D-bq
0 / 0 / 0
Регистрация: 15.04.2012
Сообщений: 20
1

[Вопрос] Перехват прерывания прямым доступом к вектору прерывания

06.05.2012, 21:01. Просмотров 4288. Ответов 20
Метки нет (Все метки)

Всех приветствую!
В данный момент разбираюсь с обработкой аппаратного прерывания (прерывание таймера 08h и 1Ch, -//- клавиатуры 09h). Освоил способ с помощью функций 25h и 35h.
Но не могу понять, как сделать тоже самое прямой записью (установить и возвратить текущее значение вектора..).
Прошу помощи!
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.05.2012, 21:01
Ответы с готовыми решениями:

Обработчик прерывания и перехват прерывания
Доброе время суток, я чтиаю книгу Калашникова-Ассемблер и уже втрой день не могу понять почему...

перехват прерывания
напишите пожалуйста почему перехват прерывания происходит именно в этой строчке int 16h ...

Глобальный перехват аппаратного прерывания
Такой вопрос: обычный перехват прерывания клавиатуры (написанный под ДОС) работает только в рамках...

вопрос (прерывания).
Обьясните, пожалуйста, в общих чертах, что делаю эти функции. 01h 02h 09h 0Ah Спасибо.

прерывания
Здравствуйте, подскажите, пожалуйста, как осуществить прерывание при нажатии на какую-то кнопку...

20
programmisto
92 / 137 / 0
Регистрация: 15.04.2012
Сообщений: 1,032
07.05.2012, 07:07 2
Это задачка очень простая. Вектора прерывания находится в памяти по адресу 0000h:0000h. Вначале идет смещение, затем сегмент. Например, тебе нужно обработчик на 8 прерывание посадить. 8*4(длина элемента) = 20h, то есть по адресу 0000H:0020h находится смещение обработчика прерывания, а по адресу 0000H:0022h - сегмент обработчика. Просто читаешь оттуда начальный адрес, сохраняешь его у себя в резидентной, затем запихиваешь туда адрес своего обработчика и остаешься резидентом. Когда выходишь читаешь из своего буфера, ставишь по адресу исходный адрес и выходишь.
0
AFP
649 / 336 / 37
Регистрация: 04.04.2012
Сообщений: 887
07.05.2012, 10:47 3
Немного добавлю. Перед изменением в системной области память, надо запретить аппаратные прерывания командой CLI, а после внесения изменений разрешить - STI. Так надежней будет.
0
programmisto
92 / 137 / 0
Регистрация: 15.04.2012
Сообщений: 1,032
07.05.2012, 13:54 4
А, ну да, я у Калашникова читал такое про изменение стековых указателей. Это правда, особенно про таймер, потому что таймер может вылететь чертикуда. И непонятно, что будет с ДОСОм. Скорее всего упадет.
0
Go.D-bq
0 / 0 / 0
Регистрация: 15.04.2012
Сообщений: 20
07.05.2012, 19:03  [ТС] 5

Не по теме:

не получилось на готовом примере(


Вот код, работает с функциями 35h\25h, но стоит "попытаться" напрямую к вектору обратится, то зацикливается... Может не так обращаюсь. Вот код оригинальной программы (могу и свою с ошибками):
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
;INT_N  equ 8   ;прерывание таймера (IRQ0)
;INT_N  equ 9   ;прерывание клавиатуры (IRQ1)
INT_N   equ 1Ch ;прерывание таймера BIOS - программный аналог int 8
 
.186
.model small
.stack 2048
 
.code
 
;----- данные ----
;(расположены в секции кода для удобного доступа из обработчика)
 
;адрес предыдущего обработчика прерывания
old_int     label dword
old_int_o   dw ?
old_int_s   dw ?
 
;символ и аттрибут для вывода на экран
char0       label word
            db '*'
attr0       db 0
 
;----- обработчик прерывания -----
int_proc:
    pusha
    push es
    mov ax,0B800h
    mov es,ax
    xor di,di
    cld
    mov ax,char0
    mov cx,80
set_attr:
    and ah,0Fh
    stosw
    inc ah
    loop set_attr
    inc ah
    mov attr0,ah
    pop es
    popa
    jmp old_int 
 
;----- основная программа -----
entry:
;установка текстового видеорежима 80x25, 16 цветов
    mov ax,3
    int 10h
 
;получение адреса текущего обработчика прерывания   
    mov ax,3500h or INT_N
    int 21h
    mov old_int_o,bx
    mov old_int_s,es
;установка нового обработчика
    mov ax,2500h or INT_N
    lea dx,int_proc
    push cs
    pop ds
    int 21h
 
;ждать нажатия клавиши Escape
wait_esc:
    mov ah,8
    int 21h
    cmp al,27
    jne wait_esc
 
;восстановить стандартную обработку прерывания
    mov ax,2500h or INT_N
    lds dx,old_int
    int 21h
 
;выход из программы 
    mov ax,4C00h
    int 21h
 
end entry
0
programmisto
92 / 137 / 0
Регистрация: 15.04.2012
Сообщений: 1,032
08.05.2012, 07:33 6
Цитата Сообщение от Go.D-bq Посмотреть сообщение
mov ax,2500h or INT_N
О, какой подход прикольный.
Go.D-bq, знаешь почему у тебя виснет. Ты ставь вначале cli и sti после, потому что если кто-то обратится к прерыванию, когда ты меняешь, то пойдет программа непонятно куда. Мой совет - cli перед сменой и sti после смены. Ну а для таймера это просто обязательно. Int 25h и Int 35h блокирует прерывания перед сменой тоже.
1
Charles Kludge
Клюг
7647 / 3162 / 383
Регистрация: 03.05.2011
Сообщений: 8,382
08.05.2012, 10:34 7
ВотЪ, поправил немножко.О_о
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
;INT_N  equ 8   ;прерывание таймера (IRQ0)
;INT_N  equ 9   ;прерывание клавиатуры (IRQ1)
INT_N   equ 1Ch         ;прерывание таймера BIOS - программный аналог int 8
Vector_1Ch_ofs  Equ 4*1Ch   ;
Vector_1Ch_seg  Equ 4*1Ch+2 ;
 
.model  small
.386
.stack  2048
 
.code
 
;----- данные ----
;(расположены в секции кода для удобного доступа из обработчика)
 
;адрес предыдущего обработчика прерывани
;old_int     label dword
;old_int_o   dw ?
;old_int_s   dw ?
    Old_isr1C   dd ?
;символ и аттрибут для вывода на экран
    char0   label word
    db  '*'
    attr0   db 0
 
;----- обработчик прерывания -----
int_proc:
    pushf
    call    dword ptr cs:Old_isr1C
    pusha
    push    es
    mov ax,0B800h
    mov es,ax
    xor di,di
    cld
    mov ax,char0
    mov cx,80
set_attr:
    and ah,0Fh
    stosw
    inc ah
    loop    set_attr
    inc ah
    mov attr0,ah
    pop es
    popa
    retf    2
 
;----- основная программа -----
entry:
;установка текстового видеорежима 80x25, 16 цветов
    mov ax,3
    int 10h
 
;получение адреса текущего обработчика прерывани
    push    es
    push    0
    pop es
    push    word ptr es:Vector_1Ch_seg;
    push    word ptr es:Vector_1Ch_ofs
    pop word ptr cs:Old_isr1C   ;
    pop word ptr cs:Old_isr1C+2
;установка нового обработчика
    cli
    push    offset int_proc
    push    cs
    pop word ptr es:Vector_1Ch_seg
    pop word ptr es:Vector_1Ch_ofs
    sti
    pop es
;ждать нажатия клавиши Escape
wait_esc:
    mov ah,8
    int 21h
    cmp al,27
    jne wait_esc
 
;восстановить стандартную обработку прерывани
    mov ax,2500h or INT_N
    lds dx, Old_isr1C
    int 21h
 
;выход из программы
    mov ax,4C00h
    int 21h
 
    end entry
Цитата Сообщение от programmisto
mov ax,2500h or INT_N
О, какой подход прикольный.
Слепи макрос. Слабо?
1
programmisto
92 / 137 / 0
Регистрация: 15.04.2012
Сообщений: 1,032
08.05.2012, 13:53 8
Цитата Сообщение от Charles Kludge Посмотреть сообщение
Слепи макрос. Слабо?
Нет. Вот макрос для замены вектора в DS:SI адрес нового обработчика, в CL - номер:
Assembler
1
2
3
4
5
6
setvector macro
mov dx,si
mov al,cl
mov ah,35h
int 21h
setvector endm
и для получения, в CL - номер прерывания, на выходе: DX:SI - адрес вектора
Assembler
1
2
3
4
5
6
getvector macro
mov al,cl
mov ah,25h
int 21h
mov si,dx
getvector endm
ВСЕ!
0
Charles Kludge
Клюг
7647 / 3162 / 383
Регистрация: 03.05.2011
Сообщений: 8,382
08.05.2012, 14:29 9
Цитата Сообщение от programmisto
ВСЕ!
Копипаста не в счёт. К тому же там mov al, cl - лишнее.
Через замену обработчика напрямую, сохранение старого и т.д. Типа SetVector IntNum, MyHandler и RestoreVector IntNum. Ы?
0
Go.D-bq
0 / 0 / 0
Регистрация: 15.04.2012
Сообщений: 20
08.05.2012, 16:02  [ТС] 10
Ребят, благодарю!

Не по теме:

сижу вот теперь в отладчик, с листом бумаги и разбираюсь: втолкнул в стек, вытолкнул из стека..:umnik:


Код получается снова нагруженный.. Просто я не знаю шаблона для простого написания прерывания.. Части раскиданы по все программе
Есть какая-нибудь программа, на которую можно опереться как шаблон? Что-то типа этого не встречали? : процедура (вызов-запрет-цикл выводимого сообщений) - главная часть - EXIT ?

Не по теме:

Может просто где натыкались на такое.. А то будет сложно потом знакомым объяснять другим что за функции типа retf или lds своими словами.

0
programmisto
92 / 137 / 0
Регистрация: 15.04.2012
Сообщений: 1,032
09.05.2012, 06:25 11
Цитата Сообщение от Go.D-bq Посмотреть сообщение
опереться как шаблон
Смотри образец обработчика прерывания:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
olddat dd 0
 
push 0
pop es
mov bx,номер прерывания*4
mov olddat,es:[bx]
mov es:[bx],word ptr offset Int_x_proc
mov es:[bx+2],word ptr seg Int_x_proc
 
Int_x_proc proc
 
;здесь делаем махинации.
 
push [olddat+2]
pop es
mov bx,[olddat]
call es:bx
iret
Int_x_proc endp
int 21h
;оставляем резидентной
P.S.эксперты, подскажите, как прогу резидентной оставить. Справочку небольшую.
1
Charles Kludge
Клюг
7647 / 3162 / 383
Регистрация: 03.05.2011
Сообщений: 8,382
09.05.2012, 08:40 12
Цитата Сообщение от programmisto
Справочку небольшую.
RU.ASM.CHAINIK FAQ
0
Go.D-bq
0 / 0 / 0
Регистрация: 15.04.2012
Сообщений: 20
12.05.2012, 13:08  [ТС] 13

Не по теме:

Виноват за долгую задержку в коде ;)


Проверьте на правильность, может что лучше заменить-переделать?
Вопрос в шапке указан! Вот сам код! :
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
.model  small
.386
.stack  200h
.code
 
;----- данные ----
;(расположены в секции кода для удобного доступа из обработчика)
 
;адрес предыдущего обработчика прерывани
    Old_1Ch   dd ?
;символ и аттрибут для вывода на экран
    char   label word
    db  '*'     ;00101010b
    attr   db 0
;----- обработчик прерывания -----
int_proc_1Ch:
    pushf
    call    dword ptr cs:Old_1Ch
    pusha
    push    es
    mov ax,0B800h
    mov es,ax
    xor di,di
    cld
    mov ax,char
    mov cx,80
set_attr:
    and ah,00001111b
    mov es:[di],ax
    add di,2
    inc ah
    loop    set_attr
    inc ah
    mov attr,ah
    pop es
    popa
    iret
;----- основная программа -----
main:
;установка текстового видеорежима 80x25, 16 цветов, + очистка экрана 
    mov ax,3
    int 10h
;получение адреса текущего обработчика прерывани
    push    es
    push    0
    pop es
    push    word ptr es:4*1Ch+2;
    push    word ptr es:4*1Ch 
    pop word ptr cs:Old_1Ch   ;
    pop word ptr cs:Old_1Ch+2
;установка нового обработчика
    cli
    push    offset int_proc_1Ch
    push    cs
    pop word ptr es:4*1Ch+2
    pop word ptr es:4*1Ch 
    sti
    pop es
;ждать нажатия клавиши Esc
wait_esc:
    mov ah,8
    int 21h
    cmp al,27
    jne wait_esc
;восстановить стандартную обработку прерывани
    mov dx,word ptr Old_1Ch
    mov ds,word ptr Old_1Ch+2
;выход из программы
    mov ax,4C00h
    int 21h
    end main
0
Charles Kludge
Клюг
7647 / 3162 / 383
Регистрация: 03.05.2011
Сообщений: 8,382
12.05.2012, 13:16 14
стр. 29,30 можно заменить на одну:
Assembler
1
stosw
0
Go.D-bq
12.05.2012, 14:02  [ТС]
  #15

Не по теме:

Момент всплыл грустный: программа то отработает нормально, то может с ошибкой.. Перепроверил код - тщетно.
Не знаю куда копать пока...

0
Charles Kludge
Клюг
7647 / 3162 / 383
Регистрация: 03.05.2011
Сообщений: 8,382
12.05.2012, 14:09 16
В стр. 68 забыто восстановление старого вектора.
0
Go.D-bq
0 / 0 / 0
Регистрация: 15.04.2012
Сообщений: 20
12.05.2012, 14:44  [ТС] 17
Понятно. Просто суть была перевести команды:
Assembler
1
2
3
mov ax,2500h or 1Ch
    lds dx, Old_1C
    int 21h
в эквивалентные с прямой записью :) Но я не справился(

Не по теме:

Исправляю ..

0
Charles Kludge
Клюг
7647 / 3162 / 383
Регистрация: 03.05.2011
Сообщений: 8,382
12.05.2012, 14:57 18
Цитата Сообщение от Go.D-bq
Но я не справился(
Кхе... Лишнее зачеркнуть:
Assembler
1
2
3
4
5
6
7
8
9
;восстановить стандартную обработку прерывани
    push    es
    push    0
    pop es
    cli 
    push    dword ptr cs:Old_isr1C
    pop dword ptr es:4*1Ch
    sti
    pop es
0
Go.D-bq
0 / 0 / 0
Регистрация: 15.04.2012
Сообщений: 20
12.05.2012, 15:05  [ТС] 19
Charles Kludge Сделал так:
Assembler
1
2
3
4
5
6
7
push 0
    pop es
    pushf
    cli 
    mov eax,dword ptr Old_1Ch
    mov dword ptr es:[4*1Ch],eax
    popf

Не по теме:

Сделал сам и вижу ваш код :) Все равно благодарю! :good:

0
Charles Kludge
Клюг
7647 / 3162 / 383
Регистрация: 03.05.2011
Сообщений: 8,382
12.05.2012, 15:14 20
Может, pushf/popf убрать, а вместо popf - sti ? И pop es забыт.
0
12.05.2012, 15:14
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.05.2012, 15:14

Прерывания
Знатоки assemblera помогите написать программку Замаскировать прерывания от клавиатуры. По...

Прерывания
Кто знает как через прерывания узнать свое оборудование на ПК(мать, проц, видяха)? Я читал что это...

C++ и прерывания
Возникла,такая ситуация:при выполнении прерывания (int 10h) в Visual studio и Borland C++ всплывают...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru