infinite loop "div ax, bx" in bochs

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
sebihepp
Member
Member
Posts: 195
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

infinite loop "div ax, bx" in bochs

Post by sebihepp »

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
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: infinite loop "div ax, bx" in bochs

Post by AJ »

Hi,

Divide by zero? Overflow?

Any chance of seeing the code?

Cheers,
Adam
sebihepp
Member
Member
Posts: 195
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: infinite loop "div ax, bx" in bochs

Post by sebihepp »

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

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
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: infinite loop "div ax, bx" in bochs

Post by Love4Boobies »

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? #-o
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: infinite loop "div ax, bx" in bochs

Post by Brendan »

Hi,
AJ wrote:Divide by zero? Overflow?
It's 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
Note: This code is entirely untested...
Love4Boobies wrote:Besides, there are no exceptions in real mode.
All of the exceptions are possible in real mode except for "invalid TSS", "page fault" and "segment not present"...


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.
sebihepp
Member
Member
Posts: 195
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: infinite loop "div ax, bx" in bochs

Post by sebihepp »

Now I know why I had some "xor dx, dx" instructions in my code. :oops:
I optimized them away. :roll:
Thanks
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: infinite loop "div ax, bx" in bochs

Post by AJ »

sebihepp wrote:I optimized them away...
:lol: Nice word for it - whenever I write buggy code it must be due to my unnecessary optimizations :)

Cheers,
Adam
sebihepp
Member
Member
Posts: 195
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: infinite loop "div ax, bx" in bochs

Post by sebihepp »

Now I have tested your code. I had only change

Code: Select all

mov cx, al
to

Code: Select all

mov cl, al
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
sebihepp
Member
Member
Posts: 195
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: infinite loop "div ax, bx" in bochs

Post by sebihepp »

I got it!!!!! :D
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"
sebihepp
Member
Member
Posts: 195
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: infinite loop "div ax, bx" in bochs

Post by sebihepp »

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!!!
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: infinite loop "div ax, bx" in bochs

Post by Brendan »

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. :oops:

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
Hope that's closer to being right (but it's still untested)... :)


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.
sebihepp
Member
Member
Posts: 195
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: infinite loop "div ax, bx" in bochs

Post by sebihepp »

Thanks very much! But I just have progged my own version. :)

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
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.
Post Reply