0

I try to write my own keyboard interrupt handler (DOS is used), which only writes a message on the screen. When keyboard is not pressed, there another message is printed without end (so there is no way to stop program normally, but it doesn't matter). When lines of DOS interrupt in MYTASK routine are comented, interrupt handler works well, but since they are uncommented, my program crashes ("illegal instruction encountered"). Where could I made a mistake?

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
Jack D.
  • 33
  • 4
  • Maybe a typo or bad copy/paste while developing your code - but I think you mean to do `mov AH,25h` `mov AL,09h` `int 21h` .. You used `mov AL, 1c`. `1c` is the system timer tick vector. – Michael Petch Dec 10 '17 at 21:16
  • 2
    You also have to concern yourself with the fact that [DOS isn't re-entrant](http://oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_18/CH18-3.html). So if the keyboard interrupt fires will in the middle of a DOS interrupt call you may could run into the issue of things screwing up. – Michael Petch Dec 10 '17 at 21:24
  • What environment do you run your code under (just curious)? – Michael Petch Dec 10 '17 at 21:40
  • I run this code in an old ASM Tool program, which includes TASM and MASM. – Jack D. Dec 10 '17 at 22:31
  • Do tose tools run under 32-bit Windows or do you have to use something like DosBOX, DOSEMU, QEMU (plus a real version of DOS) etc? – Michael Petch Dec 10 '17 at 22:45
  • This tool runs under 32-bit Windows without use of DosBOX and other similar tools. – Jack D. Dec 11 '17 at 12:10

1 Answers1

4

None of the DOS functions are re-entrant.

What this means is that if the CPU is in the middle of executing DOS's "write string" function and gets interrupted by an IRQ that enters (uses) the "write string" function; you can expect that internal variables, etc that the interrupted "write string" was already using may be trashed by the second "write string"; and data that the second "write string" expects to find in a default state may be in a different state because the first "write string" is using it.

More specifically; I suspect that DOS switches to its own internal stack when you call a DOS function (because it doesn't know how much space is left on the caller's stack); so when DOS is "re-entered" it switches to the same stack that's already in use and overwrites all the data on the stack (potentially including data the IRQ handler needs to use to return to the code it interrupted).

Brendan
  • 35,656
  • 2
  • 39
  • 66