Sign in to follow this  
kordova

ASM - timer hook - local variable?

Recommended Posts

I'm using TASM (16bit .exe) for this. I'm trying to integrate the 18.2 timer into my assembly code and it is exhibiting some weird behavior. Basically what I'm doing is this, I have a main procedure that sets up the timer, which I'm sure is being called. I have the following globals:
X               dw   11
timerIntSeg     dw   1
timerIntOffset  dw   1

The timer set up code:
    push ds
    push cs
    pop ds
    ;Get the user defined timer interupt vector
    mov ax, 351Ch
    int 21h
    mov timerIntSeg, es
    mov timerIntOffset, bx
    
    ;Set it to the demo timer
    mov ah, 25h
    mov dx, OFFSET timerInt
    int 21h
    pop ds

Again, the timer is being called. The main procedure code:
    mov bx,X

    mov ah,6
    mov dl,bl
    int 21h

    xor ax,ax 	; function 00h - get a key
    int 16h 	; call BIOS service

    mov bx,X

    mov ah,6
    mov dl,bl
    int 21h

    xor ax,ax 	; function 00h - get a key
    int 16h 	; call BIOS service

And the end of the main procedure where the timer is reset/called:
END_PROGRAM:
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;      Reset the timer interrupt          ;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    mov ax, 251Ch
    mov dx, timerIntOffset
    mov bx, timerIntSeg
    mov ds, bx
    int 21h

    mov ax,4C00h 		; exit to DOS
    int 21h

    ;Here is where we redraw and check if escape has been pressed
timerInt:
   
    mov bx,X

    mov ah,6
    mov dl,bl
    int 21h
    inc X
endTimer:
    iret

    main endp

As you can see, the program should do the following: print X (11, or the male sign) - this works wait for keypress print X wait for keypress exit Those steps work. However, during this, the timer should print out x (which it sort of does), and then increment x. What is really happening: X prints as character 11 The timer prints the characters, starting from 0 (null) and incrementing, then at keypress character 11 is printed again, then the timer prints out continuing from the last character it printed. Textually: 11 0 1 2 3 4 5 6 (keypress)11 7 8 9 10 11 12 (keypress)(exit) Any ideas on this? Is x treated as a local variable or something like that? [Edited by - kordova on September 29, 2004 9:53:01 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Konfusius
dunno... perhaps you should write [x] instead of x... not sure though

Thermo

[X] comes out the same as X. I'm using TASM.

Share this post


Link to post
Share on other sites
What assembler are you using? Different assemblers use different ways of accessing variables; some require you to use [X], some will work with just X.

It looks okay to me.. 'X' is not a local variable (that sort of concept doesn't really exist in an assembler). Is everything in the same segment? Is this a .COM file?

cheers
sam

Share this post


Link to post
Share on other sites
Quote:
Original post by izzo
What assembler are you using? Different assemblers use different ways of accessing variables; some require you to use [X], some will work with just X.

It looks okay to me.. 'X' is not a local variable (that sort of concept doesn't really exist in an assembler). Is everything in the same segment? Is this a .COM file?

cheers
sam

It's Tasm, and by default (as far as I can tell) it's generating .exe's. (And it's 16bit in case that wasn't obvious)

Share this post


Link to post
Share on other sites
Quote:
Original post by izzo
What assembler are you using? Different assemblers use different ways of accessing variables; some require you to use [X], some will work with just X.

It looks okay to me.. 'X' is not a local variable (that sort of concept doesn't really exist in an assembler). Is everything in the same segment? Is this a .COM file?

It's an .exe, and I'm rather new to this.

I have a .data where the above data is defined and then a .code like this:

.code
main proc
mov ax,@data ; set up DS to point to data segment
mov ds,ax ; use ax

PROGRAM_ENTRY:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Init/Set User Timer ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push ds
push cs
pop ds
;Get the user defined timer interupt vector
mov ax, 351Ch
int 21h
mov timerIntSeg, es
mov timerIntOffset, bx

;Set it to the demo timer
mov ah, 25h
mov dx, OFFSET timerInt
int 21h
pop ds

PROGRAM_LOGIC_ENTRY:

mov bx,[X]

mov ah,6
mov dl,bl
int 21h

xor ax,ax ; function 00h - get a key
int 16h ; call BIOS service


mov bx,X

mov ah,6
mov dl,bl
int 21h

xor ax,ax ; function 00h - get a key
int 16h ; call BIOS service

END_PROGRAM:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Reset the timer interrupt ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax, 251Ch
mov dx, timerIntOffset
mov bx, timerIntSeg
mov ds, bx
int 21h

mov ax,4C00h ; exit to DOS
int 21h

timerInt:

mov bx,[X]

mov ah,6
mov dl,bl
int 21h
;inc [X]
inc X

endTimer:
iret

main endp

end main

Share this post


Link to post
Share on other sites
I can't figure it out exactly, but I can only guess that you are messing up your DS at some point (Because of that 11, 0, 1, 2, 3, 4, 5, 6, 11, 7, 8... behaviour, really looks like you are writing somewhere to foreign unused memory).

What I wonder is why you do this:

push ds
push cs
pop ds

....

pop ds.

The first pop is supposedly giving you access to your data, like in a COM program (I know my english is bad), nothing wrong, but the second pop restores it to its previous value, which might not be what you want.
Sorry, I am too sleepy now to be of better help (as if I ever could be :) )

KonfuThermo

Share this post


Link to post
Share on other sites
You're right. Putting:
mov ax,@data ; set up DS to point to data segment
mov ds,ax ; use ax

At the head of the interrupt does it.

Is this a solution or what is wrong that I could correct?

Share this post


Link to post
Share on other sites
Quote:
Original post by Konfusius
What I wonder is why you do this:

push ds
push cs
pop ds

....

pop ds.

The first pop is supposedly giving you access to your data, like in a COM program (I know my english is bad), nothing wrong, but the second pop restores it to its previous value, which might not be what you want.
Sorry, I am too sleepy now to be of better help (as if I ever could be :) )

KonfuThermo

Well, I was told that ds must equal cs when setting the timer. It seems to work. I tried:
mov ax,@data
mov ds,ax

After all the timer setup code and it didn't seem to work.

Quote:
Original post by Konfusius
If I am right, just pop that ds at the very end, and you should be fine.

Do you mean get rid of the pop? It is popping right now...

Share this post


Link to post
Share on other sites
If you can access your data correctly with ds=cs, that means ds must equal cs in the other code as well, else you will not be writing to the data you previously accessed.
That means, don't pop ds directly after setting up the ISR, but after you uninstalled the ISR.

Thermo

Share this post


Link to post
Share on other sites
Quote:
Original post by Konfusius
If you can access your data correctly with ds=cs, that means ds must equal cs in the other code as well, else you will not be writing to the data you previously accessed.

Thermo

But it reads x correctly after the setting up (and pop ds) in the main procedure. Does the ds=cs mess up the code in the timer for some reason?

Share this post


Link to post
Share on other sites
Yeah the problem is that your data isn't in the same segment as your code.

So in your ISR you should do what you wrote:

mov ax, @data
mov ds, ax

You might want to also save ds at the start of your ISR and restore it at the end.

The reason you set ds to cs in the setup code is because that DOS interrupt requires ds to be the segment of your ISR, and your ISR code is in your code segment.

cheers
sam

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this