Помощь - Поиск - Пользователи - Календарь
Полная версия: прерывание по нажатию комбинации клавиш
Форум «Всё о Паскале» > Delphi, Assembler и другие языки. > Assembler
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
;-----------------------------------------------
;жЁЄ«, Ё§ Є(r)в(r)а(r)Ј(r) ¬(r)¦­(r) ўл(c)вЁ в(r)«мЄ(r) ­ ¦ вЁҐ¬ Є« ўЁиЁ 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? Я попробывал - у меня не получилось....
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.