Reputation: 79
I want to print "Hello." every 55ns. what am I doing wrong?
.model small
.stack 100h
pusha MACRO
push ax
push bx
push cx
push dx
push sp
push bp
push si
push di
ENDM
popa MACRO
pop di
pop si
pop bp
pop sp
pop dx
pop cx
pop bx
pop ax
ENDM
.data
old_vec dw 1 dup(?)
old_seg dw 1 dup(?)
HELLO db "HELLO.$"
.code
start:
mov ax, @data
mov ds, ax
mov ax, es:[20h]
mov bx, es:[20h+2] ;saving the old ISR ADDRESS
mov old_vec, ax
mov old_seg, bx
mov es:[20h], OFFSET PRINT_HELLO ; setting the ivt to point to PRINT_HELLO
mov es:[20h + 2], SEG PRINT_HELLO
COMMENT @
mov bx, offset old_vec
mov ax, word ptr[bx]
mov es:[20h], ax
mov bx, offset old_seg
mov ax, word ptr[bx]
mov es:[20h+2], ax
@
;for1:
; jmp for1
.exit
mov ah, 4ch
int 21h
PRINT_HELLO proc far
pushf
pusha
mov ax, offset old_seg
mov bx, ax
mov es, word ptr[bx]
mov bx, offset old_vec
mov bx, word ptr[bx]
call far PTR es:[bx] ; calling the old interrupt handler
mov dx, offset HELLO
mov ah, 09h
int 21h
popa
iret
PRINT_HELLO endp
end
The comments are used for debugging...
2 more question -
Thanks a lot!!!
Upvotes: 2
Views: 222
Reputation: 39676
I want to print "Hello." every 55ns
I believe you meant 55 milliseconds (ms) and not nanoseconds (ns).
You don't need to hook any interrupt handler for this objective. All it takes is monitoring the BIOS.TimerTick and print the message as soon as the tick changes. That's what next program does. The executable will be a .COM program that starts up with CS
==DS
==ES
==SS
. The ORG 256
directive is mandatory.
; This program prints a message every 55 milliseconds
; until a key is pressed
ORG 256
xor ax, ax
mov es, ax
More: mov al, [es:046Ch] ; BIOS.Timer
Wait: cmp al, [es:046Ch]
je Wait
mov dx, Msg
mov ah, 09h ; DOS.PrintString
int 21h
mov ah, 01h ; BIOS.TestKey
int 16h ; -> AX ZF
jz More
mov ah, 00h ; BIOS.GetKey
int 16h ; -> AX
mov ax, 4C00h ; DOS.Terminate
int 21h
; --------------------------------
Msg db 'Hello, once every 55 milliseconds!', 13, 10, '$'
Of course it is possible to do this hooking the timer vector. In the absence of more special requirements, you should hook the 1Ch vector and leave the 08h vector be.
; This program prints a message every 55 milliseconds
; until a key is pressed
ORG 256
mov ax, 351Ch ; DOS.GetInterruptVector
int 21h ; -> ES:BX
mov [chain+1], bx
mov [chain+3], es
mov dx, int1C
mov ax, 251Ch ; DOS.SetInterruptVector
int 21h
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
; In the 'main' part you can freely change DS, ES, and SS segment registers
main: mov ah, 01h ; BIOS.TestKey
int 16h ; -> AX ZF
jz main
mov ah, 00h ; BIOS.GetKey
int 16h ; -> AX
; In the 'main' part you can freely change DS, ES, and SS segment registers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
mov dx, [cs:chain+1]
mov ds, [cs:chain+3]
mov ax, 251Ch ; DOS.SetInterruptVector
int 21h
mov ax, 4C00h ; DOS.Terminate
int 21h
; --------------------------------
int1C: push ax bx si
cld
mov bx, 0007h ; DisplayPage and GraphicsColor
mov si, Msg
.more: lods byte [cs:si]
mov ah, 0Eh ; BIOS.Teletype
int 10h
cmp al, 10
jne .more
pop si bx ax
chain: jmp far 0:0 ; Chaining to the old interrupt handler
Msg: db 'Hello, once every 55 milliseconds!', 13, 10, '$'
; --------------------------------
I used the FASM assembler. Even if you're using a MASM style assembler can you learn from these examples...
Although it is possible to do all the above from a TSR, putting this many text characters on the screen in rapid succession will inevitably make a real mess! Do remember that the foreground program (DOS command line or user application) has first pick when it comes to using the screen.
Upvotes: 4