Assembly on DOS (TASM), creating TSR with a new handler on int 21h
Asked Answered
I

3

1

I have a trouble with making TSR com file for DOS. It should set a new handler on a 21'th interrupt, terminate and stay resident. New handler should transfer control to an old interrupt 21h handler. I save its interrupt vector, but have no idea how to call it correctly. Here is a program:

.model tiny
.data
    old_int21h dw ?, ?
.code
org 100h
start:

    ;saving old interrupt vector
    mov ax, 3521h
    int 21h
    mov [old_int21h], bx
    mov [old_int21h + 2], es

    ;setting new interrupt vector
    cli
    push ds
    push cs
    pop ds
    lea dx, myint21h
    mov ax, 2521h
    int 21h
    pop ds
    sti

    ; TSR
    lea dx, start
    int 27h

myint21h proc
    ; doing something
    ; want to transfer control to an old interrupt 21h handler here. How?
    iret
myint21h endp

end start
Issykkul answered 27/2, 2013 at 18:40 Comment(2)
Which version of DOS?Mannose
Using dosbox with DOS v.5.00Issykkul
I
2

I understood the problem. The right solution is here. "Right" isn't sure "optimal", but works nice anyway, and it isn't hard enough to optimize this code now.

.model tiny
.code
org 100h
start:

    ; saving old interrupt vector
    mov ax, 3521h
    int 21h
    mov [old_int21h], bx
    mov [old_int21h + 2], es

    ; setting new interrupt vector
    cli
    push ds
    push cs
    pop ds
    lea dx, myint21h
    mov ax, 2521h
    int 21h
    pop ds
    sti

    ; TSR
    mov dx, 00ffh
    mov ax, 3100h
    int 21h

    ; here comes data & hew handler part
    old_int21h dw ?, ?

    myint21h proc
                    ; some stuff
                    ; transfer control to an old interrupt 21h handler
        push word ptr [cs:old_int21h + 2] ; segment
        push word ptr [cs:old_int21h]     ; offset
        retf
    myint21h endp

end start

The answer below was almost right :)

Issykkul answered 1/3, 2013 at 5:18 Comment(0)
R
2

My 16-bit DOS ASM is a bit rusty, but if I recall correctly you need to do this:

push word ptr [old_int21h + 2] ; segment
push word ptr [old_int21h]     ; offset
retf
Realtor answered 27/2, 2013 at 19:1 Comment(3)
Note that this is a jump to the old handler - control does not return to your hook but directly to the original caller (if you kept the stack intact - if not it will probably just blow up instead :)Realtor
Is it working on your DOS? When I use this, dosbox freezes after first int 21h. Is my program correct in general? Stack is kept intact.Issykkul
Unfortunately, I don't actually have a working environment at my disposal that I could do 16-bit DOS development on. Back when I did DOS ISR/TSR work, and I have, I had things like SoftICE at my disposal to aid when things went south, which they often did - this stuff is not easy to get right.Realtor
I
2

I understood the problem. The right solution is here. "Right" isn't sure "optimal", but works nice anyway, and it isn't hard enough to optimize this code now.

.model tiny
.code
org 100h
start:

    ; saving old interrupt vector
    mov ax, 3521h
    int 21h
    mov [old_int21h], bx
    mov [old_int21h + 2], es

    ; setting new interrupt vector
    cli
    push ds
    push cs
    pop ds
    lea dx, myint21h
    mov ax, 2521h
    int 21h
    pop ds
    sti

    ; TSR
    mov dx, 00ffh
    mov ax, 3100h
    int 21h

    ; here comes data & hew handler part
    old_int21h dw ?, ?

    myint21h proc
                    ; some stuff
                    ; transfer control to an old interrupt 21h handler
        push word ptr [cs:old_int21h + 2] ; segment
        push word ptr [cs:old_int21h]     ; offset
        retf
    myint21h endp

end start

The answer below was almost right :)

Issykkul answered 1/3, 2013 at 5:18 Comment(0)
I
-1
     .model tiny
     .code
     org 100h
     start:

; Inicializando la fecha para LotusWorks
    mov ax, 2A21h
    int 21h
    mov [Reg_DX], dx
        sub cx,064h
    mov [Reg_CX], cx

; saving old interrupt vector
    mov ax, 3521h
    int 21h
    mov [old_int21h], bx
    mov [old_int21h + 2], es

; setting new interrupt vector

    cli
    push ds
    push cs
    pop ds
    lea dx, myint21h
    mov ax, 2521h
    int 21h
    pop ds
    sti

     ; TSR
    mov dx, 00ffh
    mov ax, 3100h
    int 21h

     ; here comes data & hew handler part

    old_int21h dw ?, ?
    Reg_DX     dw ?, ?
    Reg_CX     dw ?, ?

     myint21h proc

       cmp ah,2ah
       jne S1
           cmp al,56h
           je  S2
           mov ah,02h
           int 01AH
           cmp cx,0
           jne Mismodia
           mov ax,02A56h
           int 21h
      mov [CS:Reg_DX], dx

MismoDia:
       mov cx, [cs:Reg_CX]
       mov al,00
       mov dx, [cs:Reg_DX]
       iret

       S2:
           mov al,0

       S1:
        ; transfer control to an old
        ; interrupt 21h handler


        push word ptr [cs:old_int21h + 2]   ; segment
        push word ptr [cs:old_int21h]       ; offset
        retf
    myint21h endp

     end start
Impeachable answered 12/2, 2020 at 14:16 Comment(1)
Welcome to Stack Overflow! Thank you for this code snippet, which might provide some limited short-term help. A proper explanation would greatly improve its long-term value by showing why this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please edit your answer to add some explanation, including the assumptions you've made.Edwinaedwine

© 2022 - 2024 — McMap. All rights reserved.