0
votes

I am trying to write an assembly language program which will:

  1. Use interrupts,
  2. Print "Hello world" string on screen when 7 ticks lapse on timer interrupt, and
  3. Stay resident after termination.

I've tried printing a string on screen using interrupts. How can I implement timer interrupt for printing a string on lapse of 7 ticks in counter, and to make it resident after termination.

; program that will print a string by hooking timer interrupt
[org 0x0100]
    jmp start
tickcount:  dw  0

message:    db  'Hello world'

printmsg:   mov ah, 0x13        ; service 13 - print string
        mov bl, 7           ; normal attribute
        mov dx, 0x0100      ; row 1 column 0
        mov cx, 11          ; length of string
        push    cs
        pop es          ; segment of string
        mov bp, message     ; offset of string
        int 0x10            ; call BIOS video service

timer:      push    ax
        inc word [cs:tickcount] ; increment tick count
        push    word [cs:tickcount]
        call    printmsg        ; print string on 7 ticks

        mov al, 0x20
        out 0x20, al        ; end of interrupt

        pop ax
        iret                ; return from interrupt

start:      xor ax, ax
        mov es, ax          ; point es to IVT base
        cli             ; disable interrupts
        mov word[es:8*4], timer ; store offset at n*4
        mov [es:8*4+2], cs      ; store segment at n*4+2
        sti             ; enable interrupts

        mov dx, start       ; end of resident portion
        add dx, 15          ; round up to next para
        mov cl, 4
        shr dx, cl          ; number of paras
        mov ax, 0x3100      ; terminate and stay resident
        int 0x21

On execution, program doesn't show a string on screen and cursor freezes.

1
Is this the assignment where you have to print your student ID after the number of clock ticks equal to the last digit of your ID? - Michael Petch
Yes, I've solved it. :) - Hamza

1 Answers

2
votes

You can't just take over the timer interrupt like that. Your timer interrupt needs to pass control to the original timer interrupt at regular intervals. You can do that by saving the original value of the int 8 handler before you replace it, then in your interrupt handler do a far jump to this location rather than signaling the end-of-interrupt or doing an iret. (If you change the rate of timer interrupts, there is a bit more complexity that would need to be added to keep the original timer tick interrupt called at the correct frequency.)

Your printmsg function changes registers that you have not saved which will corrupt the code that was running before the timer tick occurred, nor does it return properly, instead falling thru into your original interrupt handler.