Bochs stuck on 'DIV' instruction

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
Cjmovie

Bochs stuck on 'DIV' instruction

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

Re:Bochs stuck on 'DIV' instruction

Post 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?
Cjmovie

Re:Bochs stuck on 'DIV' instruction

Post 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?
Ushma

Re:Bochs stuck on 'DIV' instruction

Post 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?
AR

Re:Bochs stuck on 'DIV' instruction

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

Re:Bochs stuck on 'DIV' instruction

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

Re:Bochs stuck on 'DIV' instruction

Post 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.
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re:Bochs stuck on 'DIV' instruction

Post by bubach »

@Cjmovie: Wow, Windows paying attention to their own stuff? :P
Thanks for the info, it might come in handy.
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
Post Reply