Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

NASM version of John Santic's stderr to stdout TSR

30 views
Skip to first unread message

Rod Pemberton

unread,
Apr 14, 2010, 2:25:49 PM4/14/10
to

The code below is a binary compatible NASM conversion
of John Santic's stderr to stdout TSR from:
http://johnsantic.com/comp/tsr.html


Rod Pemberton


; STDERROR.ASM

BITS 16
ORG 0x100 ; require for .COM file
SECTION .text

start: jmp short start1
nop

old_vector: dw 00h,00h ; save old DOS int 21 vector

start1:
mov ax, 0
mov es, ax
les bx, [es:21h * 4] ; read the vector for DOS int 21
mov [old_vector], bx ; save it so we can chain to it
mov [old_vector + 2], es
mov ax, 0
mov es, ax
cli ; disable interrupts while we write

mov word [es:21h * 4], isr ; chain our handler to DOS int 21
mov [es:(21h * 4) + 2], cs
sti ; enable interrupts
mov ax, 3100h ; function code to become resident
mov dx, last / 16 + 11h ; reserve memory paragraphs for us
int 21h ; return to DOS but remain resident

; This interrupt service routine is chained to the main DOS int 21 vector.

isr: cmp ah, 40h ; function code = write to file?
jne exit ; jump if no, don't do anything
cmp bx, byte 2 ; handle = stderr?
jne exit ; jump if no, don't do anything
dec bx ; force handle to stdout
exit: jmp far [cs:old_vector] ; let DOS do its thing

last equ $ - start ; how much memory we use

pe...@nospam.demon.co.uk

unread,
Feb 15, 2011, 1:17:27 AM2/15/11
to
In article <hq5193$5pq$1...@speranza.aioe.org>
do_no...@havenone.cmm "Rod Pemberton" writes:

I'm not sure if the main aim was binary or functional compatibility,
but locating the initialisation/setup code at the end will result in a
smaller memory footprint of the resident code. I.e.

start: jmp short start1
nop ;;-------> I guess this is for compat??

old_vector: dw 00h,00h ; save old DOS int 21 vector

; This interrupt service routine is chained to the main DOS int 21 vector.

isr: cmp ah, 40h ; function code = write to file?
jne exit ; jump if no, don't do anything
cmp bx, byte 2 ; handle = stderr?
jne exit ; jump if no, don't do anything
dec bx ; force handle to stdout
exit: jmp far [cs:old_vector] ; let DOS do its thing

last equ $ - start ; how much memory we use

; ----> we don't need to keep this code resident


start1:
mov ax, 0
mov es, ax
les bx, [es:21h * 4] ; read the vector for DOS int 21
mov [old_vector], bx ; save it so we can chain to it
mov [old_vector + 2], es
mov ax, 0
mov es, ax
cli ; disable interrupts while we write

mov word [es:21h * 4], isr ; chain our handler to DOS int 21
mov [es:(21h * 4) + 2], cs
sti ; enable interrupts
mov ax, 3100h ; function code to become resident
mov dx, last / 16 + 11h ; reserve memory paragraphs for us
int 21h ; return to DOS but remain resident

As a final comment, the ISR itself could be made even smaller :)

; This interrupt service routine is chained to the main DOS int 21 vector.

isr: cmp ah, 40h ; function code = write to file?
jne exit ; jump if no, don't do anything
cmp bx, byte 2 ; handle = stderr?
jne exit ; jump if no, don't do anything
dec bx ; force handle to stdout

exit: db 0xEA ; "jmp far immediate" opcode


old_vector: dw 00h,00h ; save old DOS int 21 vector

Pete
--
"We have not inherited the earth from our ancestors,
we have borrowed it from our descendants."

0 new messages