Page 1 of 1

Bochs stuck on 'DIV' instruction

Posted: Sun Sep 11, 2005 4:28 pm
by Cjmovie
I'm NO expert on ASM, I'm completly self taught by example in that area. Well, I've got my FAT bootloader in testing stages, but the ReadSector function never returns (or reads the sectore).

So I ran BochsDbg, and found it was stuck in the LBA to CHS area, on this instruction
(0) [0x00007cab] 0000:7cab (unk. ctxt): div al, byte ptr ds:0x7c3f ; f6363f7c
I have also probed the memory area 0x7C3F and found it to be equal to 2 (as expected), the number of heads on the floppy drive. The entire section of code is:

Code: Select all

;Sector = LBA%SectorsPerTrack + 1
 div BYTE [SectorsPerTrack] ;LBA%SectorsPerTrack
 inc dx                   ;Increase remainder (add 1)
 mov BYTE [Counter0], dl  ;Save Sector Number
 
 ;Cylinder= (LBA/SectorsPerTrack)%Heads
 ;AX is already (LBA/SectorsPerTrack)
 xor dx, dx               ;Make it 0
 div BYTE [NumHeads]      ;Divide by NumHeads (2)
 mov BYTE [Counter1], dl  ;Save value (remainder)
 
 ;Head = (LBA/SectorsPerTrack)/Heads
 ;AX is already (LBA/SectorsPerTrack/Heads)
 mov dh, ah               ;Put Head (qoutient) in BIOS arg.
The 'AX' register contains the sector to read (In LBA) at the start of the code. Counter0 - Counter2 are Misc. use byte-size variables. As you can see it goes directly from the last instruction to reading the sector, as I don't have to save the Head value in a variable.

Re:Bochs stuck on 'DIV' instruction

Posted: Sun Sep 11, 2005 6:09 pm
by Kemp
What do you mean exactly by stuck on that instruction? The disassembly looks fine to me. Do you mean it sits there looping on that instruction, that it panics on that instruction, that it gives an incorrect answer?

Re:Bochs stuck on 'DIV' instruction

Posted: Sun Sep 11, 2005 7:09 pm
by Cjmovie
Literally stuck - It keeps showing that one, step after step.

Also, I found that clearing out DX for the DIV fixes it, but I'd still like to know why.


Another question:
FAT has two FATs for backup purposes, and as the Microsoft reference says, most drivers don't even mess with the second. I was wondering - Would it be possible to install a second-phase bootloader into the redundant fat section, then have the first bootloader load it. Then that one can use the first FAT to load the correct files. That way I could use sectors 10-19 and have a bootloader that is at most 5K, so I could do some fancy loading. The real problem is if it will consider it a bad disk or try to fix it - what do you think?

Re:Bochs stuck on 'DIV' instruction

Posted: Sun Sep 11, 2005 7:28 pm
by Ushma
It seems to me that if it's being used as a backup table, correct FAT drivers should update both tables when they update one. So even I only look at the first, I'll still update the second, so Windows (or whatever else) putting files on your bootdisk'll run that 2nd stage right over. Is that initial thought actually wrong?

Re:Bochs stuck on 'DIV' instruction

Posted: Sun Sep 11, 2005 8:07 pm
by AR
DX is where the remainder is stored, IIRC it is also used as the high part of the input (ie. AX:DX - WORD operand, EAX:EDX - DWORD operand), so by not zeroing DX you may be overflowing something.

Also FAT Floppies usually only have 1 FAT, there are only 2 on Hard disks. IIRC, There is also a flag to disable the second or more FATs which you have to check before trying to use the others.

Re:Bochs stuck on 'DIV' instruction

Posted: Sun Sep 11, 2005 8:26 pm
by Brendan
Hi,
AR wrote: DX is where the remainder is stored, IIRC it is also used as the high part of the input (ie. AX:DX - WORD operand, EAX:EDX - DWORD operand), so by not zeroing DX you may be overflowing something.
There's 2 ways to cause a "Divide Error Exception" - the first is division by zero, while the second is overflow. The 16 bit unsigned divide is AX = (DX:AX) / DIVISOR with the remainder in DX. If the divisor is small and DX:AX is large, then the result may not fit in AX. For example, if DX=0x2222, AX = 0x4444 and the divisor is 2, then 0x22224444 / 2 = 0x11112222 and you get a divide error.

For the code posted an 8 bit unsigned divide is used ("div BYTE [SectorsPerTrack]"), which doesn't use DX at all. Instead it's AL = AX / DIVISOR, with the remainder stored in AH. This means that the entire thing is messed up, and that the contents of DX shouldn't make a difference to either division and won't contain any of the results either.


Cheers,

Brendan

Re:Bochs stuck on 'DIV' instruction

Posted: Mon Sep 12, 2005 7:52 pm
by Cjmovie
Thanks!

Also, found out how to use floppy as FAT12 while still having a bootloader load sectors without a FAT reader - Put the total number of sectors less than the real amount, then place the second stage at the end! It works, as windows DOES pay attention to that value, and reports the floppy having a total 1.15MB of space.

Re:Bochs stuck on 'DIV' instruction

Posted: Tue Sep 13, 2005 2:03 am
by bubach
@Cjmovie: Wow, Windows paying attention to their own stuff? :P
Thanks for the info, it might come in handy.