Помощь - Поиск - Пользователи - Календарь
Полная версия: прерывание по нажатию комбинации клавиш
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ассемблер
kile
всем привет smile.gif.
у меня 3 вопроса:

1. как написать прерывание, которое по нажатию комбинации двух клавиш (например Ctrl+printScr или Alt+PrintScr) выдавало бы например ткстовое сообщение ?? (в досе)

2. какой код у клавиши PrintScr ???

3. как сдлать енто прерывние резидентным ??
BlackShadow
Потешно ты выразился smile.gif
1). Сделать тебе надо вот что: перехватить прерывание 09h, и там читать скан-коды из порта клавы. В нужный момент (когда нажали то, чего ты хотел) выводить своё сообщение.Только советую тут видеорежим проверять.
2). Код клавиши PrintScr не помню.
3). Пишешь обычный TSR, в которм и проворачиваешь п. 1
kile
черная тень, ты выразился не менее потешно =))) ;)
нельзя ли поподробней....
BlackShadow
1). Прерывание 09h возникает при нажатии на клавишу. Чтобы его перехватить и среагировать раньше, чем обычный обработчик нужно его вектор настроить на свою функцию (см. в АЗЫ). Для этого можно воспользоватьяс INT 21h, а можно просто изменить указатель по адресу 0000:09h*4 = 00024h на адрес своей функции (только предыдущий адрес сохранить не забудь).
Функция твоя должна считывать скан-код клавиши из порта клавиатуры, сравнивать с кодом PrintScr и, если не то, то вызывать старый обработчик, иначе творить что тебе там надо. Только не забывай регистры сохранять! Делается это примерно так:
PUSH AX
IN AL,60h
CMP AL,PRINT_SCR_CODE
JE Handle
POP AX
JMP [FAR PTR CS:OLD_VECTOR]

Handle:
IN AL,61h
MOV AH,AL
OR AL,80h
OUT 61h,AL
MOV AL,AH
OUT 61h,AL
DELAY_CHEGO_TO_TAM:
VIHOD:
MOV AL,20h
OUT 20h,AL
IRET

Ну, или что-то похожее.
2). Код PrintScr - 37h
3). Чтобы сделать резидентной свою программу, нужно в AL занести код выхода, в AH 31h, в DX - адрес первого ненужного байта в твоей программе и вызвать INT 21h. DOS выгрузит всё, что начинается с CS:DX, а остальное оставит и пометит эту память, как зарезервированную. Так что TSR'ы лучше писать как COM'ики, а обработчики прерываний размещать в самом начале, тогда всё остальное можно будет выгрузить безболезненно.
kile
знакомо ли вам состояние, когда 4 часа пишешь программу, а она не работает ???? angry.gif ...
почему мое долбаное прерывние не работает ?? мне надо по нажатию Shift+PrinScreen вывести звуковой сигнал (или тектовое сообещние).

пользователь запускает программу, после чего комп ждет нажатия шифт+принтскрин. когда нужная комбинация нажата, программа завершается.

резидентой делать не надо.

  DATSEG SEGMENT

EndLine EQU '$'

KEEP_CS DW 0 ; segment
KEEP_IP DW 0 ; offsetя

line1 DB 'LAB WORK ь5.', 0AH, 0DH, Endline
line2 DB 'PRESS Shift+PrintScreen TO RUN INTERRUPT.', 0AH, 0DH, Endline
line3 DB 'PROGRAM WILL DO SOUND SIGNAL.', 0AH, 0DH, Endline;
line4 DB 'done', 0AH, 0DH, Endline;
line5 DB 'end of program', 0AH, 0DH, Endline;
flag DW 0

;top_of_st LABEL WORD

DATSEG ENDS
;-----------------------------------------------
STKSEG SEGMENT STACK
DW 4096 DUP ('?')
STKSEG ENDS
;-----------------------------------------------
LAB5 SEGMENT PARA PUBLIC
ASSUME CS : lab5, DS : DATSEG, ES : NOTHING, SS : STKSEG
ORG 100H

start: ; MOV SP, OFFSET top_of_st
MOV AX, DATSEG
MOV DS, AX
JMP Begin
;-----------------------------------------------
WriteStr PROC NEAR
XOR AX, AX
MOV AH, 09H
INT 21H
RET
WriteStr ENDP
;-----------------------------------------------
SUB_INT PROC FAR

PUSH AX
PUSH DX
PUSH DS

MOV AH, 02H
MOV DL, 07H
INT 21H
я
;mov dx,OFFSET line4 ;line5

; push ds
; mov ax, seg line4 ;line5
; mov ds,ax
; call writeStr
; pop ds


;mov cx,60000
;@l2: nop
; push cx
; mov cx,50000
;@l1: nop
; loop @l1
; pop cx
; loop @l2
; push ds
; mov ax, seg flag
; mov ds,ax
; mov dx,offset flag
mov flag, 0000h
; pop ds

POP DS
POP DX
POP AX

MOV AL, 20H
OUT 20H, AL
IRET
SUB_INT ENDP


BEGIN :
MOV flag, 1
MOV DX, OFFSET line1
CALL WriteStr

MOV AH, 35H ; function of getting vector
MOV AL, 05H ; number of vector
INT 21H

MOV KEEP_IP, BX ; remember offset я
MOV KEEP_CS, ES ; remember segment

MOV DX, OFFSET line2
CALL WriteStr

;------------------- SET THE INTERRUPT ---------

PUSH DS
MOV DX, OFFSET SUB_INT
MOV AX, SEG SUB_INT я
MOV DS, AX
MOV AH, 25H
MOV AL, 05H
INT 21H

MOV AL, 20H ; ???????????
OUT 20H, AL ; ???????????
POP DS
;-----------------------------------------------
;жЁЄ«, Ё§ Є®в®а®Ј® ¬®¦­® ўл©вЁ в®«мЄ® ­ ¦ вЁҐ¬ Є« ўЁиЁ ESC
;LOO1:
;MOV AH,06H
;MOV DL,0FFH
;INT 21H
;JZ LOO1
;CMP AL, 27
;JNZ LOO1

@lo2: mov cx,200
mov bx,flag
cmp bx,0
jz @fin
jmp @lo2

@fin: mov dx,OFFSET line3
call writeStr
;------------------- RESTORE ORIGINAL VECTOR ---
CLI
PUSH DS
MOV DX, KEEP_IP
MOV AX, KEEP_CS
MOV DS, AX
MOV AH, 25H
MOV AL, 05H
INT 21H

MOV AL, 20H ; ???????
OUT 20H, AL ; ???????

POP DS
STI
;-----------------------------------------------
;mov dx,OFFSET line4
;call writeStr
;xor ax,ax

MOV AX, 4C00H
INT 21H

MOV AL, 20H ; ??????
OUT 20H, AL ; ??????

lab5 ENDS
END start

kile
подскажите пожалуста, а то нервных клеток в моем теле к понедельнику не останется =((((((((
BlackShadow
Цитата
MOV AL, 20H ; ???????????
OUT 20H, AL ; ???????????

Я вот тоже этого не понял. Какое это ты тут аппаратное прерывание завершаешь?
Цитата
@lo2: mov cx,200

А это к чему?
Цитата
MOV AX, 4C00H
INT 21H    ----------- Тут выполнение заканчивается. Вообще.

MOV AL, 20H ; ??????    ----------- До этого бреда дело уже не доходит.
OUT 20H, AL ; ??????


А тут твоя основная ошибка:
Цитата
mov flag, 0000h

Эта команда интерпретируется как "MOD [DS:flag],0", не грех кстати размер указать, а вот DS к этому моменту может оказаться иным.
И не аппаратное прерывание 05h - не надо его завершать таким образом. Или ты просто решил наторкать эти строки повсеместно, так на всякий случай???

И ещё 1 вопрос: ты уверен, что INT 05h вызывается из INT 09h при нажатии на Shift+PrtSc? Я попробывал - у меня не получилось....
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.