Hi,
I can't find a bug in the code that would explain the symptoms; but...
yasar11732 wrote:
Am I doing everything properly here?
A signed 16-bit integer has a range from -32768 to +32768 (a total of 65536 values). If it's incremented 1000 times per second it'll overflow every 65536/1000 = 65.536 seconds.
Now let's see what happens when the "timer_ticks" contains +32767 and you call this code with "milliseconds to sleep = 10":
Code:
/* put milliseconds to sleep in %ax, %ax trashed */
sleep:
push %bx
mov timer_ticks,%bx ;bx = +32767
add %bx,%ax ;ax = +32767 + 10 = -32759 due to overflow
sleep0:
mov timer_ticks,%bx ;bx = +32767 still
cmp %bx,%ax
jle sleep1 ;if(-32759 <= +32767) exit the loop
hlt
jmp sleep0
sleep1:
pop %bx
ret
What this means is that sometimes it will return immediately with no delay at all.
Note: It's more common to use unsigned integers (e.g. "jbe sleep1"), but you'd have the same bug in that case (e.g. "65535 + 10 = 9 due to overflow").
To fix both of these, try something like:
Code:
/* put milliseconds to sleep in %ax, %ax trashed */
sleep:
push %cx
push %bx
mov timer_ticks,%cx ;cx = starting tick
sleep0:
mov timer_ticks,%bx ;bx = current tick
sub %cx,%bx ;bx = current tick - starting tick = time passed
cmp %ax,%bx
jae sleep1 ;If time passed >= delay exit the loop
hlt
jmp sleep0
sleep1:
pop %bx
pop %cx
ret
This code should be immune to overflows.
Also note that if you ask for a 1 ms delay immediately before the timer IRQ occurs you could delay for almost no time at all. Essentially the code waits for between (AX-1) and AX milliseconds (and doesn't wait for at least AX milliseconds). To fix that you can change the the branch to "ja sleep1".
Cheers,
Brendan