Solved

need help with timer interrupt (08)

Posted on 2003-11-11
13
923 Views
Last Modified: 2012-06-21
hi, i'm have problems with my timer interrupt handler. the handler is supposed to clear everything in "NN" to 0.  i replaced the original timer interrupt handler. but when the clock "ticks",  NN is not being cleared.  does anyone know why?  could it possibly be because my program ends before the clock gets a chance to to tick?  here is the code below. thanks for any help you guys can give.



                   .data
NN      db    3 dup (0)

      .code

old8_seg      dw      0            ; old int 8 seg
old8_off      dw      0            ; old int 8 off

begin:      cli          ; don't want timer to interrupt
      mov      ah,35h            ; get address of
      mov      al,8            ;   timer interrupt handler
      int      21h                  ; go do it
      mov      old8_seg,es            ; save timer
      mov      old8_off,bx            ;   interrupt address

      mov      ax,seg clearNN      ; put segment address of the new
      mov      ds,ax            ;   interrupt handler into ds
      mov      dx,offset clearNN      ; set up offset
      mov      ah,25h                  ; change timer
      mov      al,8                  ;   interrupt handler
      int      21h                  ;   address
      sti                        ; allow interrupt

      mov      ax,@data            ; setup
      mov      ds,ax            ;   data seg reg
                            .
                            .
                            .     body of code
                            .
      mov      ax,old8_seg    ; put segment address of the old
      mov      ds,ax            ;   interrupt handler into ds
      mov      dx,old8_Off     ; set up offset of old int handler
      mov      ah,25h            ; change timer
      mov      al,8            ;   interrupt handler
      int      21h            ;   address

; the interrupt handler
ClearNN:
      cli                  ; dont' want timer to interrupt
      push      ax            ; save the
      push      cx            ;   4 general
      push      dx            ;   purpose
      push      bx            ;   registers
      push      ds            ; save data seg reg
      pushf                  ; save flags register

      mov      ax,@data            ; setup up
      mov      ds,ax            ;   data seg reg

      mov      cx,3                  ; init counter
      xor      dx,dx                  ; clear dx
      mov      bx,offset NN                      ; pt to NRU map
clrnxtbyt:
      mov      [bx],dx            ; clear current byte in NRU
      inc      bx                  ; pt to next byte
      dec      cx                  ; dec counter
      cmp      cx,0                  ; above 0?
      ja      clrnxtbyt            ; if yes, clear next byte

      popf            ; retrieve flags register
      pop      ds      ; retrieve data seg reg
      pop      bx                  ; retrieve the
      pop      dx                  ;  4 general
      pop      cx                  ;  purpose
      pop      ax                  ;  registers      
      sti                        ; allow interrupts
      iret            ; ret to place before interrupt occurred
0
Comment
Question by:shaie_boi
13 Comments
 
LVL 22

Expert Comment

by:grg99
ID: 9721970
It's often a problem with the wrong offsets or segments.  You have to be sure the offsets are computed relative to "@data, not the DGroup.

.  Use "debug" to step thru your setup code.   Make sure the linker hasnt messed up you  concept of "@data".  
One thing I always do is have some variable with a "passwoed" in it, like  "dw 1234h" alongsize my data.  Then I have some code that each time checks for that value in that variable.  That ensures that my asegment registers are set up properly.



Another good idea is to try calling your interrupt handler yourself with a "int" instrution. Step thru that to make sure the segments are okay.

0
 

Author Comment

by:shaie_boi
ID: 9728476
i have tried calling my interrupt handler with "int 8" and it in fact does clear "NN", but when i run the program normally it does not clear NN when the clock ticks which i want it to do.
0
 

Author Comment

by:shaie_boi
ID: 9729832
I realized that interrupt handler was actually working.  But for some reason the timer interrupt only occurs once when i run the program.  anyone know why? i've added delays within the program to let another timer interrupt occur but it never comes.

Also the interrupt handler only works if that program i run is the first one to be executed in the command prompt.  For example my program is called "PROGA".  if i run PROGA the first time it works perfectly fine.  however if i try to run PROGA in the command prompt again, the interrupt handler does not work.  also if i run PROGB first and then run PROGA, the interrupt handler will not work.  but the interrupt handler does work every single time if i double click the EXE file for PROGA.

anyone know how to solve these two problems? thanks.
0
Does Powershell have you tied up in knots?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

 
LVL 5

Expert Comment

by:mtmike
ID: 9731938
I think you should not hook int 8 directly but instead hook int 1c. It is also a good idea to chain the previous interrupt handler to yours.

And, this looks like a buffer overflow:

clrnxtbyt:
     mov     [bx],dx          ; clear current byte in NRU

-> mov [bx],dl ?
0
 

Author Comment

by:shaie_boi
ID: 9734510
whats int 1c? and how do i chain the previous interrupt handlers?
0
 
LVL 5

Expert Comment

by:mtmike
ID: 9734606
Int 1c is the user handler that is called by the int 8 timer interrupt handler. This is the recommended way of installing a timer interrupt.

http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte2h0w.htm

To chain handlers, simply invoke the previous handler at the end of your handler. So, when some other program (TSR) also hooks the timer interrupt, it continues to function normally. You already save the previous handler in old8_seg and old8_off.
0
 
LVL 5

Expert Comment

by:mtmike
ID: 9734655
0
 

Author Comment

by:shaie_boi
ID: 9735332
how do i invoke it?
0
 

Author Comment

by:shaie_boi
ID: 9735369
i've tried using "jmp dword  ptr old8_off" at the end of my handler and it prints out a whole bunch of weird things on the screen when an interrupt occurs
0
 
LVL 5

Accepted Solution

by:
mtmike earned 135 total points
ID: 9735451
A far pointer looks like segment:offset, so "jmp dword ptr old8_seg" should work.
0
 

Author Comment

by:shaie_boi
ID: 9735508
okay i tried "jmp dword ptr old8_seg" in my handler  , but now the rest of the program doesn't finish running when a timer interrupt occurs.
0
 

Author Comment

by:shaie_boi
ID: 9736288
okay i just changed the order or this:

old8_seg     dw     0          ; old int 8 seg
old8_off     dw     0          ; old int 8 off


to

old8_off     dw     0          ; old int 8 off
old8_seg     dw     0          ; old int 8 seg

and used this jmp instead in the handler:

jmp dword ptr old8_off



everything works fine now.
thanks a lot for your help
0
 

Expert Comment

by:lincoln_stern
ID: 9815681
Here is a rewrite to work correctly
Note: NN (it is changed to a 4 byte integer) is in the codesegment
so you don't have to worry about the data seg
and the old8_seg and old8_off is laid into the new
handler at the correct location.
There is no different data segment...and none to set up.
Why would you want to clear 3 bytes 18.2 times per second is unknown to me.




    .code

align 16

NN      db    4 dup (0)    ;put this in code segment..easiest way to implement



begin:
     cli               ; don't want timer to interrupt
     mov     ah,35h          ; get address of
     mov     al,8          ;   timer interrupt handler
     int     21h               ; go do it
     mov     cs:old8_seg,es          ; save timer..save explicitly in Code seg
     mov     cs:old8_off,bx          ;   interrupt address...save explicitly in Code seg

     mov     ax,cs           ; put segment address of the new
     mov     ds,ax          ;   interrupt handler into ds
     mov     dx,offset cs:clearNN     ; set up offset
     mov     ah,25h               ; change timer
     mov     al,8               ;   interrupt handler
     int     21h               ;   address
     sti                    ; allow interrupt

   

    ; please include code to stay TSR here
    ; (which *is* missing!)



; the interrupt handler
align 16
ClearNN:

      pushf
      push      EAX
      xor      EAX
      mov      cs:[NN],EAX      ;work with 4 bytes in one operation.
      POP      EAX
      popf


      jmp      far 0:0            ;this opcode is 5 bytes
old8_seg     $-4            ; old int 8 seg...initialization will place old int8 vector here
old8_off     $-2                ; old int 8 off

      ;...and timer happens, it then continues with the old int 8
      ;...because it jumped (far) to the existing code and will do iret.

0

Featured Post

ScreenConnect 6.0 Free Trial

Explore all the enhancements in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Do you use a spreadsheet like Microsoft's Excel?  Have you ever wanted to link out to a non excel file on your computer or network drive?  This is the way I found to do it!
Each year, investment in cloud platforms grows more than 20% (https://www.immun.io/hubfs/Immunio_2016/Content/Marketing/Cloud-Security-Report-2016.pdf?submissionGuid=a8d80a00-6fee-4b85-81db-a4e28f681762) as an increasing number of companies begin to…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question