infinite loop "div ax, bx" in bochs
-
- Member
- Posts: 195
- Joined: Tue Aug 26, 2008 11:24 am
- GitHub: https://github.com/sebihepp
infinite loop "div ax, bx" in bochs
Help me!
I used the debugger of Bochs and if I execute "div ax, bx", bochs switches between
this instruction and an "iret". I think my instruction raises an exception, because
the "iret" is in 0xF000:0xFF63
What's wrong?
TIA Sebihepp
I used the debugger of Bochs and if I execute "div ax, bx", bochs switches between
this instruction and an "iret". I think my instruction raises an exception, because
the "iret" is in 0xF000:0xFF63
What's wrong?
TIA Sebihepp
Re: infinite loop "div ax, bx" in bochs
Hi,
Divide by zero? Overflow?
Any chance of seeing the code?
Cheers,
Adam
Divide by zero? Overflow?
Any chance of seeing the code?
Cheers,
Adam
-
- Member
- Posts: 195
- Joined: Tue Aug 26, 2008 11:24 am
- GitHub: https://github.com/sebihepp
Re: infinite loop "div ax, bx" in bochs
I checked the registers:
ax = 0x0001, bx = 0x0BF3
Here's the code. Segments and Stack are initialized.
The parameters are an LSN-Address in ax, in the [BootDrive] the bootdrive
and the destination in es:bx
ax = 0x0001, bx = 0x0BF3
Here's the code. Segments and Stack are initialized.
The parameters are an LSN-Address in ax, in the [BootDrive] the bootdrive
and the destination in es:bx
Code: Select all
[BITS 16]
ReadSektor:
push ds
push ax
mov ax, cs
mov ds, ax
pop ax
mov [LSN], ax
push ax
push bx
push cx
push dx
push bx
mov bx, 36
div bx
mov ch, al
mov ax, [LSN]
mov bx, 18
div bx
mov cl, dl
inc cl
mov ax, [LSN]
mov bx, 18
div bx
and al, 0x01
mov dh, al
pop bx
.Load:
mov ax, 0x0201
mov dl, [BootDrive]
int 0x13
jc .Load
pop dx
pop cx
pop bx
pop ax
pop ds
ret
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: infinite loop "div ax, bx" in bochs
First you say something about an infinite loop and then something about exceptions; it's not the same. Besides, there are no exceptions in real mode. I really don't see the point for most of the stuff you do, like pushing and popping from the stack.
Your reading fails beacuse the registers passed to INT 13h aren't set right. That sets CF, which in turn loops.
EDIT: That IRET at 0xF000:0xFF63 is probably where the BIOS handler is. There's nothing wrong with it. You call an interrupt. Interrupts are supposed to have IRETs, right?
Your reading fails beacuse the registers passed to INT 13h aren't set right. That sets CF, which in turn loops.
EDIT: That IRET at 0xF000:0xFF63 is probably where the BIOS handler is. There's nothing wrong with it. You call an interrupt. Interrupts are supposed to have IRETs, right?
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
Re: infinite loop "div ax, bx" in bochs
Hi,
The (16-bit) division instruction divides "DX:AX" by the divisor (and doesn't just divide AX by the divisor), and because DX is never set to zero it's likely that result will overflow AX. For example, if DX = 0xFFFF and AX = 0x0001 on entry, then the first division would try to do "0xFFFF0001 / 36 = 0x71C6AAA" and then overflow because 0x71C6AAA won't fit into 16-bits...
That's not the only bug though (the calculation for the sector number is wrong too)...
What you want might go something like this:
Note: This code is entirely untested...
Cheers,
Brendan
It's overflow.AJ wrote:Divide by zero? Overflow?
The (16-bit) division instruction divides "DX:AX" by the divisor (and doesn't just divide AX by the divisor), and because DX is never set to zero it's likely that result will overflow AX. For example, if DX = 0xFFFF and AX = 0x0001 on entry, then the first division would try to do "0xFFFF0001 / 36 = 0x71C6AAA" and then overflow because 0x71C6AAA won't fit into 16-bits...
That's not the only bug though (the calculation for the sector number is wrong too)...
What you want might go something like this:
Code: Select all
;Input
; ax Logical sector number
; es:bx Address to load the sector
;
;Output
; carry set if failed to load
readSektor:
pusha
push word 4 ;Number of retries = 4
xor dx,dx ;dx:ax = logical sector number
mov cx,18 ;cx = divisor
div cx ;ax = sector - 1, dx = remainder = "logical track number"
mov cx,al ;ch = 0, cl = sector - 1
inc cl ;cl = sector
shr dx,1 ;dh = 0, dl = cylinder, carry = head
mov cl,dl ;cl = track
adc dh,dh ;dh = head
mov dl, [cs:BootDrive] ;dl = device
.retry:
mov ax, 0x0201 ;ah = BIOS function number (read sector/s), al = number of sectors to read
int 0x13 ;Try to load sector
jnc .done ;Done if no error
sub [sp],1 ;Decrease retry counter
jnc .retry ;Retry if counter >= 0
.done:
pop ax ;Remove retry counter from stack (can't do "add sp,2" without trashing carry)
popa
ret
All of the exceptions are possible in real mode except for "invalid TSS", "page fault" and "segment not present"...Love4Boobies wrote:Besides, there are no exceptions in real mode.
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.
-
- Member
- Posts: 195
- Joined: Tue Aug 26, 2008 11:24 am
- GitHub: https://github.com/sebihepp
Re: infinite loop "div ax, bx" in bochs
Now I know why I had some "xor dx, dx" instructions in my code.
I optimized them away.
Thanks
I optimized them away.
Thanks
Re: infinite loop "div ax, bx" in bochs
Nice word for it - whenever I write buggy code it must be due to my unnecessary optimizationssebihepp wrote:I optimized them away...
Cheers,
Adam
-
- Member
- Posts: 195
- Joined: Tue Aug 26, 2008 11:24 am
- GitHub: https://github.com/sebihepp
Re: infinite loop "div ax, bx" in bochs
Now I have tested your code. I had only change
to
But everytime I use this function I get an error in Bochs:
int13_diskette: read/write/verify: parameter out of range
I use this code in a loop to load all sectors from the floppy.
I removed all instructions from my code, that the only things left are
a loop with count 2880, ax = 0 and bx = 0, wich calls this function.
I still get an error, so I think the error must be in this function.
TIA Sebihepp
Code: Select all
mov cx, al
Code: Select all
mov cl, al
int13_diskette: read/write/verify: parameter out of range
I use this code in a loop to load all sectors from the floppy.
I removed all instructions from my code, that the only things left are
a loop with count 2880, ax = 0 and bx = 0, wich calls this function.
I still get an error, so I think the error must be in this function.
TIA Sebihepp
-
- Member
- Posts: 195
- Joined: Tue Aug 26, 2008 11:24 am
- GitHub: https://github.com/sebihepp
Re: infinite loop "div ax, bx" in bochs
I got it!!!!!
The track have to be in ch, not in cl. ^^
Edit:
And another error:
It must be "mov cl, dl", and not "mov cl, al"
The track have to be in ch, not in cl. ^^
Edit:
And another error:
It must be "mov cl, dl", and not "mov cl, al"
-
- Member
- Posts: 195
- Joined: Tue Aug 26, 2008 11:24 am
- GitHub: https://github.com/sebihepp
Re: infinite loop "div ax, bx" in bochs
Next error: ch (track) is calculated wrong!
This function tell me, that LSN 0x0A is Head=0, Sector=0x0B (That' is right, but...)
Track=0x05!!!
This function tell me, that LSN 0x0A is Head=0, Sector=0x0B (That' is right, but...)
Track=0x05!!!
Re: infinite loop "div ax, bx" in bochs
Hi,
I think I must've been having a bad day - for the first division, I got the quotient and remainder around the wrong way, which caused most of the problems.
Anyway, try this version:
Hope that's closer to being right (but it's still untested)...
Cheers,
Brendan
I think I must've been having a bad day - for the first division, I got the quotient and remainder around the wrong way, which caused most of the problems.
Anyway, try this version:
Code: Select all
;Input
; ax Logical sector number
; es:bx Address to load the sector
;
;Output
; carry set if failed to load
readSektor:
pusha
push word 4 ;Number of retries = 4
xor dx,dx ;dx:ax = logical sector number
mov cx,18 ;cx = divisor
div cx ;dh = 0, dl = sector - 1, ax = remainder = "logical track number"
mov cl,dl ;ch = 0, cl = sector - 1
inc cl ;cl = sector
shr ax,1 ;al = cylinder, carry = head
mov ch,al ;ch = track
adc dh,ah ;dh = head
mov dl, [cs:BootDrive] ;dl = device
.retry:
mov ax, 0x0201 ;ah = BIOS function number (read sector/s), al = number of sectors to read
int 0x13 ;Try to load sector
jnc .done ;Done if no error
sub [sp],1 ;Decrease retry counter
jnc .retry ;Retry if counter >= 0
.done:
pop ax ;Remove retry counter from stack (can't do "add sp,2" without trashing carry)
popa
ret
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.
-
- Member
- Posts: 195
- Joined: Tue Aug 26, 2008 11:24 am
- GitHub: https://github.com/sebihepp
Re: infinite loop "div ax, bx" in bochs
Thanks very much! But I just have progged my own version.
It works! The only thing wich I doesn't understand is, why Bochs tell me:
"increment_sector: Clamping Cylinder to max"
All works fine, only this Warning is in the Logbook.
Code: Select all
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ax (in) - Linear Sektor Number
; bx (in) - Offset
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[BITS 16]
ReadSektor:
pusha
xor dx, dx
mov cx, 18
div cx
mov cl, dl
inc cl
mov ch, al
shr ch, 0x01
mov dh, ch
and dh, 0x01
mov dl, [BootDrive]
.Load:
mov ax, 0x0201
int 0x13
jc .Load
popa
ret
"increment_sector: Clamping Cylinder to max"
All works fine, only this Warning is in the Logbook.