![]() |
1. Заголовок или название темы должно быть информативным
2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE]
3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора.
5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM!
6. Проверяйте программы перед тем, как выложить их на форум!!
![]() ![]() |
![]() |
Neon6868 |
![]() ![]()
Сообщение
#1
|
Пионер ![]() ![]() Группа: Пользователи Сообщений: 146 Пол: Мужской Репутация: ![]() ![]() ![]() |
Написать на ассемблере 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
Сообщение отредактировано: Neon6868 - 11.04.2008 23:27 |
andriano |
![]()
Сообщение
#2
|
Гуру ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 168 Пол: Мужской Реальное имя: Сергей Андрианов Репутация: ![]() ![]() ![]() |
1. Размещеть программу без комментариев IMHO дурной тон. Я, например, уже лет 10 не пользовался Ассемблером под DOS и, естественно, не помню наизусть номера функций DOS. Поэтому без комментариев могу только догадываться, что делает программа. Кроме того, если бы ты откомментировал, а потом сам прочитал собственные комментарии, вероятно, ты бы сам и обнаружил ошибку, не прибегая к посторонней помощи.
2. Твоя программа трижды вызывает функцию DOS. Насколько я понимаю, это: - запрос текущего (старого) вектора прерывания, - установка нового, - восстановление старого. Так вот, когда именно должен сработать твой обработчик прерывания, если ты сразу после установки нового заменяешь его обратно на старый? Да, ты заменяешь обработчик и затем возвращаешь старый, но за это время не успевает случиться ни одного прерывания. Я по номеру не мог вспомнить, какое прерывание ты переопределяешь, но если это прерывание от таймера, то между sti и cli можно вставить временную задержку. Если от клавиатуры, то ожидание нажатия на клавишу и т.п. |
Neon6868 |
![]() ![]()
Сообщение
#3
|
Пионер ![]() ![]() Группа: Пользователи Сообщений: 146 Пол: Мужской Репутация: ![]() ![]() ![]() |
2. Твоя программа трижды вызывает функцию DOS. Насколько я понимаю, это: - запрос текущего (старого) вектора прерывания, - установка нового, - восстановление старого. Все именно так и есть! ![]() У меня прерывание клавиатуры, я сделал как ты написал, но почему то все равно не работает. ![]() 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
Сообщение отредактировано: Neon6868 - 12.04.2008 16:55 |
andriano |
![]()
Сообщение
#4
|
Гуру ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 168 Пол: Мужской Реальное имя: Сергей Андрианов Репутация: ![]() ![]() ![]() |
Я уже не помню, оно ждет нажатия на клавишу?
Попытайся вставить несколько раз (3-4), т.к. вероятно, ты при запуске exe-шника нажимаешь на клавиши и программа читает уже готовый символ из буфера. Кстати, когда запускаешь программу, она ждет или сразу завершается? |
xds |
![]()
Сообщение
#5
|
![]() N337 ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 737 Пол: Мужской Репутация: ![]() ![]() ![]() |
Во-первых, поборись с этим:
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
-------------------- The idiots are winning.
|
Neon6868 |
![]()
Сообщение
#6
|
Пионер ![]() ![]() Группа: Пользователи Сообщений: 146 Пол: Мужской Репутация: ![]() ![]() ![]() |
Все исправил, вроде работает. Но я делал так, что каждый символ выводится другим цветом, но я не уверен что так и надо. Может кто знает что значит циклическая замена цвета у символов всего экрана?
|
xds |
![]()
Сообщение
#7
|
![]() N337 ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 737 Пол: Мужской Репутация: ![]() ![]() ![]() |
Я вчера такой пример заготовил:
;номер прерывания
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
-------------------- The idiots are winning.
|
![]() ![]() |
![]() |
Текстовая версия | 17.07.2025 20:14 |