Can you spot the error???

All off topic discussions go here. Everything from the funny thing your cat did to your favorite tv shows. Non-programming computer questions are ok too.
Post Reply
DLBuunk
Member
Member
Posts: 39
Joined: Sun May 18, 2008 9:36 am
Location: The Netherlands

Can you spot the error???

Post by DLBuunk »

Can you spot the error I made in my timer code? It took me two days to find it.

Code: Select all

IRQ0:
        push    ax
        mov     byte [.flag],01h
        mov     al,20h
        out     20h,al
        pop     ax
        iret
.flag:  db      00h

timer:   ;cx is number of 18.2 Hz ticks to wait
        hlt
        cmp     byte [IRQ0.flag],01h
        jne     timer
        mov     byte [IRQ0.flag],01h
        dec     cx
        cmp     cx,00h
        jne     timer
        ret
When I test it with the following code it appears to work fine:

Code: Select all

timertest:   ;print 1 '!' per second to the screen (infinite loop)
        mov     cx,12h
        call    timer
        mov    ax,0E21h
        int     10h
        jmp     timertest
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: Can you spot the error???

Post by Gigasoft »

Well, you're setting IRQ0.flag to 1, which it already is, instead of some other value. You also ought to know that the DEC instruction updates ZF, and that the LOOP instruction performs the same function as DEC CX / JNZ.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Can you spot the error???

Post by Combuster »

Four seconds. Memory operand with undefined segment register contents. (line 3)
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
bitshifter
Member
Member
Posts: 50
Joined: Sun Sep 20, 2009 4:03 pm

Re: Can you spot the error???

Post by bitshifter »

A more elegant way...

Code: Select all

IRQ0:
    inc [.ticks]
    iret
  .ticks dw 0

timer: ; cx = number of ticks to wait...
    push cx
    add cx,[IRQ0.ticks]
  .wait:
    cmp [IRQ0.ticks],cx
    jl .wait
    call print
    pop cx
    ret
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Can you spot the error???

Post by Brendan »

Hi,
Combuster wrote:Four seconds. Memory operand with undefined segment register contents. (line 3)
That may be intentional. I do my OS like that - data segment registers treated as constants, with some tricky "general protection fault" handler code to reset them if some idiot changes them (and no hope or desire to support Virtual8086). Segment register loads are slow... ;)
bitshifter wrote:A more elegant way...
A more buggy way (you forgot to send the EOI to the PIC, there's "roll over" bugs, and you don't HLT to save power). 8)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Can you spot the error???

Post by Owen »

Isn't DS going to change every time you enter user space anyway? Or is your OS x86_64 only? (I can't ascertain with the OP's but I'd guess not)

Particularly on i386 I'd be wary about using wrong segment registers since any API I'd define for x86 would have LDT support (Some things require the ability to create their own segments - an example is WINE)
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Can you spot the error???

Post by Combuster »

Brendan wrote:Hi,
Combuster wrote:Four seconds. Memory operand with undefined segment register contents. (line 3)
That may be intentional. I do my OS like that - data segment registers treated as constants, with some tricky "general protection fault" handler code to reset them if some idiot changes them (and no hope or desire to support Virtual8086). Segment register loads are slow... ;)
Given the use of 16-bits registers throughout, including as arguments to an interrupt call within the intel-reserved range (another potential bug), I assumed it was written for real mode.

And who said the bug was not a GPF? :mrgreen:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Can you spot the error???

Post by Owen »

Combuster wrote:
Brendan wrote:Hi,
Combuster wrote:Four seconds. Memory operand with undefined segment register contents. (line 3)
That may be intentional. I do my OS like that - data segment registers treated as constants, with some tricky "general protection fault" handler code to reset them if some idiot changes them (and no hope or desire to support Virtual8086). Segment register loads are slow... ;)
Given the use of 16-bits registers throughout, including as arguments to an interrupt call within the intel-reserved range (another potential bug), I assumed it was written for real mode.

And who said the bug was not a GPF? :mrgreen:
It could be 16-bit protected mode...

(Yeah, right...)
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: Can you spot the error???

Post by Gigasoft »

bitshifter wrote:A more elegant way...
This has the same lack of CS: override as above, and it also introduces 3 new problems. It doesn't perform an EOI, it doesn't conserve energy, and it has an integer overflow problem. Here's a more correct version that waits for an exact number of 18.2ths of a second:

Code: Select all

IRQ0:
        push    ax
        mov     byte [cs:.flag],01h
        mov     al,20h
        out     20h,al
        pop     ax
        iret
.flag:  db      00h

timer:   ;cx is number of 18.2 Hz ticks to wait
        mov al,34h ; Reset timer
        out 43h,al
        mov al,0
        out 40h,al
        out 40h,al
.tmr2:
        mov [IRQ0.flag],0
.tmr1:
        hlt
        cmp byte [IRQ0.flag],0
        jz     .tmr1
        loop     .tmr2
        ret
Post Reply