1. Заголовок или название темы должно быть информативным 2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE] 3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали! 4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора. 5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM! 6. Проверяйте программы перед тем, как выложить их на форум!!
прерывание по нажатию комбинации клавиш, объясните
1. как написать прерывание, которое по нажатию комбинации двух клавиш (например Ctrl+printScr или Alt+PrintScr) выдавало бы например ткстовое сообщение ?? (в досе)
Потешно ты выразился 1). Сделать тебе надо вот что: перехватить прерывание 09h, и там читать скан-коды из порта клавы. В нужный момент (когда нажали то, чего ты хотел) выводить своё сообщение.Только советую тут видеорежим проверять. 2). Код клавиши PrintScr не помню. 3). Пишешь обычный TSR, в которм и проворачиваешь п. 1
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'ики, а обработчики прерываний размещать в самом начале, тогда всё остальное можно будет выгрузить безболезненно.
знакомо ли вам состояние, когда 4 часа пишешь программу, а она не работает ???? ... почему мое долбаное прерывние не работает ?? мне надо по нажатию 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
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? Я попробывал - у меня не получилось....