2017-12-10 1 views
0

화면에 메시지 만 쓰는 자체 키보드 인터럽트 처리기 (DOS 사용)를 작성하려고합니다. 키보드를 누르지 않으면 다른 메시지가 끝없이 인쇄됩니다 (따라서 프로그램을 정상적으로 중지 할 방법은 없지만 중요하지는 않습니다). MYTASK 루틴의 ​​DOS 라인 인터럽트가 흐릿 해지면 인터럽트 핸들러는 잘 작동하지만 주석 처리가 해제 되었기 때문에 프로그램이 충돌합니다 ("불법적 인 명령어가 발생했습니다"). 어디에서 실수 할 수 있었습니까?자체 제작 키보드 인터럽트 처리기

DOSSEG 
.MODEL TINY 
.STACK 100h 
.DATA 
TaskMessage DB 13,10,'Now task executed',13,10,'$' 
IHandlerMessage DB 13,10,'Now interrupt handler executed',13,10,'$' 
KEEP_CS DW 0 
KEEP_IP DW 0 
.CODE 
mov ax,@Data 
mov ds,ax 
jmp beg 

mytask proc far 
infiloop: 
;mov ah,09h 
;mov dx,OFFSET TaskMessage  ; program fails when these 3 lines 
;int 21h       ; are uncommented 
cmp bx,bx 
je infiloop 
ret 
mytask endp 

beg: 
mov AH,35h 
mov AL,09h 
int 21h 
mov KEEP_CS, ES 
mov KEEP_IP, BX   ; here I save address of old interrupt handler 

CLI 
push DS 
mov dx, offset myint 
mov ax, seg myint 
mov ds,ax 
mov AH,25h 
mov AL,09h 
int 21h   ; here I set new interrupt handler 
pop DS 
STI 

call mytask    ; here I start mytask 
jmp end123 

myint proc far   ; my keyboard interrupt handler 
push ds 
push ax 
push dx 
push cx 
mov ah,09h 
mov dx, offset IHandlerMessage 
int 21h 
pop cx 
pop dx 
pop ax 
pop ds 

push ax 
mov al,20h 
out 20h,al 
pop ax 
iret 
myint endp 

end123: 
CLI 
push DS 
mov DS, [KEEP_CS] 
mov DX, [KEEP_IP] 
mov AH,25h 
mov AL,09h 
int 21h   ; here I set old interrupt handler again, though it is 
pop DS   ; not needed in this program 
STI 
mov ah,4ch 
int 21h 
END 
+0

코드를 개발하는 동안 오타 또는 불량 복사/붙여 넣기가 발생했을 가능성이 있습니다. 그러나 'mov AH, 25h'를 할 것입니다. 'mov AL, 09h' 'int 21h' ..'mov AL, 1c '. '1c'는 시스템 타이머 틱 벡터입니다. –

+2

또한 [DOS는 재진입 불가] (http://oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_18/CH18-3.html)에 관심을 가져야합니다. 따라서 키보드 인터럽트 호출이 DOS 인터럽트 호출 중간에 발생하면 문제가 발생할 수 있습니다. –

+0

어떤 환경에서 코드를 실행합니까 (단지 궁금한가요?). –

답변

4

아무 DOS 기능도 재진입하지 않습니다.

이 의미는 CPU가 DOS의 "쓰기 문자열"기능을 실행하는 중간에 "쓰기 문자열"기능을 입력 (사용)하는 IRQ에 의해 인터럽트되면; 인터럽트 된 "쓰기 문자열"이 이미 사용하고있는 내부 변수 등이 두 번째 "쓰기 문자열"에 의해 휴지통이 될 수 있다고 예상 할 수 있습니다. 두 번째 "쓰기 문자열"이 기본 상태에서 찾기를 기대하는 데이터는 첫 번째 "쓰기 문자열"이이를 사용하기 때문에 다른 상태에있을 수 있습니다.

보다 구체적으로; DOS 함수를 호출 할 때 DOS가 자체 내부 스택으로 전환한다고 의심됩니다 (호출자의 스택에 남은 공간이 얼마인지 알지 못하기 때문에). 그래서 도스가 "재 입력"되면 이미 사용중인 동일한 스택으로 전환하고 스택의 모든 데이터를 덮어 씁니다 (인터럽트 된 코드로 돌아 가기 위해 IRQ 핸들러가 사용해야하는 데이터를 잠재적으로 포함합니다).