Помощь - Поиск - Пользователи - Календарь
Полная версия: Перехват и обработка аппаратного прерывания
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ассемблер
Neon6868
Написать на ассемблере IBM PC программу перехвата заданного аппаратного прерывания. Программа должна перехватить прерывание и продемонстрировать обработку перехваченного прерывания выводом заданного набора символов на экран прямым доступом к видеопамяти.

При этом:
• Номер прерывания – 08h
• Способ перехвата – прямым доступом к вектору прерывания
• Способ отображения – инверсия атрибутов символов всего экрана

Программа не работает, ничего не происходит после запуска! Подскажите плиз почему?

Программа:
 model small
stack 100h
.286
.data
save dw 0
cveta db 0001b,0010b,0011b,0100b,0101b,0110b,0111b,1000b,1001b,1010b,1011b,1100b,1101b,11
10b,1111b
.code
my_proc proc
pusha
mov ax,0B800h
mov es,ax
mov di,0
mov cx,2000
m1:
mov ax,es:[di]
and ah,11110000b
cmp bx,15
jbe m2
mov bx,0
m2:
add ah,cveta[bx]
mov es:[di],ax
add di,2
loop m1
popa
pop es
pop ds
pushf
call cs:[save]
iret
my_proc endp
start:
mov ax,@data
mov ds,ax
push ds
mov ax,0
mov es,ax
push es
cli
mov ah,35h
mov al,09h
int 21h
mov ax,es:[bx]
mov word ptr cs:[save],ax
mov ax,es:[bx+2]
mov word ptr cs:[save+2],ax
mov ah,25h
mov al,09h
mov dx,offset my_proc
mov ax,cs
mov ds,ax
int 21h
sti
cli
mov ah,25h
mov dx,word ptr cs:[save]
mov ds,word ptr cs:[save+2]
int 21h
sti
mov ax,4C00h
int 21h
end start
andriano
1. Размещеть программу без комментариев IMHO дурной тон. Я, например, уже лет 10 не пользовался Ассемблером под DOS и, естественно, не помню наизусть номера функций DOS. Поэтому без комментариев могу только догадываться, что делает программа. Кроме того, если бы ты откомментировал, а потом сам прочитал собственные комментарии, вероятно, ты бы сам и обнаружил ошибку, не прибегая к посторонней помощи.

2. Твоя программа трижды вызывает функцию DOS. Насколько я понимаю, это:
- запрос текущего (старого) вектора прерывания,
- установка нового,
- восстановление старого.
Так вот, когда именно должен сработать твой обработчик прерывания, если ты сразу после установки нового заменяешь его обратно на старый?
Да, ты заменяешь обработчик и затем возвращаешь старый, но за это время не успевает случиться ни одного прерывания.
Я по номеру не мог вспомнить, какое прерывание ты переопределяешь, но если это прерывание от таймера, то между sti и cli можно вставить временную задержку. Если от клавиатуры, то ожидание нажатия на клавишу и т.п.
Neon6868
Цитата(andriano @ 12.04.2008 10:59) *

2. Твоя программа трижды вызывает функцию DOS. Насколько я понимаю, это:
- запрос текущего (старого) вектора прерывания,
- установка нового,
- восстановление старого.


Все именно так и есть! smile.gif

У меня прерывание клавиатуры, я сделал как ты написал, но почему то все равно не работает. mega_chok.gif Подскажи плиз почему?

 model small
stack 100h
.286
.data
save dw 0
cveta db 0001b,0010b,0011b,0100b,0101b,0110b,0111b,1000b,1001b,1010b,1011b,1100b,1101b,11
10b,1111b
.code
my_proc proc
pusha
push ds
push es
mov ax, @data
mov ds, ax
mov ax,0B800h
mov es,ax
mov di,0
mov cx,2000
m1:
mov ax,es:[di]
and ah,11110000b
cmp bx,15
jbe m2
mov bx,0
m2:
add ah,cveta[bx]
mov es:[di],ax
add di,2
loop m1
pop es
pop ds
popa
pushf
call dword ptr cs:[save]
iret
my_proc endp
start:
mov ax,@data
mov ds,ax
mov ax,0
mov es,ax
mov ah,35h
mov al,09h
int 21h
mov word ptr cs:[save],bx
mov word ptr cs:[save+2],es
mov ah,25h
mov al,09h
mov dx,offset my_proc
mov ax,cs
mov ds,ax
int 21h

xor ax,ax
int 16h

mov ah,25h
mov dx,word ptr cs:[save]
mov ds,word ptr cs:[save+2]
int 21h
mov ax,4C00h
int 21h
end start
andriano
Я уже не помню, оно ждет нажатия на клавишу?
Попытайся вставить несколько раз (3-4), т.к. вероятно, ты при запуске exe-шника нажимаешь на клавиши и программа читает уже готовый символ из буфера.
Кстати, когда запускаешь программу, она ждет или сразу завершается?
xds
Во-первых, поборись с этим:
  mov ah,25h
mov al,09h
mov dx,offset my_proc
mov ax,cs
mov ds,ax
int 21h


Во-вторых, перенеси save в секцию .code.

В третьих, у тебя какая-то фигня в обработчике - непонятно, что же он должен сделать - bx берется "с потолка".

Добавлено через 12 мин.
+ в XP перед "прямой записью в видеопамять" надо явно "воткнуть" 3-й видеорежим
mov ax,3
int 10h
Neon6868
Все исправил, вроде работает. Но я делал так, что каждый символ выводится другим цветом, но я не уверен что так и надо. Может кто знает что значит циклическая замена цвета у символов всего экрана?
xds
Я вчера такой пример заготовил:
;номер прерывания
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
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.