Page 1 of 1

CHS and LBA Confusion

Posted: Mon Aug 08, 2011 11:26 am
by sds2017
Hello I've been building a bootloader and I've looked for code showing how to convert LBA(Liogical Block Addressing) to CHS(Cylinder, Head, Sector) and CHS to LBA(BTW I'm using FAT12). I found this code and I just don't understand the way they did this.
The formula to convert CHS to LBA:

Code: Select all

CHS to LBA
Formula    
    LBA = (cluster - 2 ) * sectors per cluster
And here the code:
          
          sub     ax, 0x0002                          ; subtract 2 from cluster number
          xor     cx, cx
          mov     cl, BYTE [bpbSectorsPerCluster]     ; get sectors per cluster
          mul     cx                                                   ;Why multiply by cx? Why not ax?

LBA to CHS
Formula:
      absolute sector 	= 	(logical sector / sectors per track) + 1
      absolute head   	= 	(logical sector / sectors per track) MOD number of heads
      absolute track 	= 	 logical sector / (sectors per track * number of heads)
Code:
    LBACHS:
          xor     dx, dx                                           
          div     WORD [bpbSectorsPerTrack]           
          inc     dl                                                   
          mov     BYTE [absoluteSector], dl               
 
          xor     dx, dx                                          
          div     WORD [bpbHeadsPerCylinder]       
          mov     BYTE [absoluteHead], dl            
 
          mov     BYTE [absoluteTrack], al            
          ret
Shouldn't the code be look this:

Code: Select all

xor dx, dx
div WORD [bpbSectorsPerTrack]
push dx
inc dx
mov BYTE [absoluteSector]
pop dx
;Then somehow get the MOD
mov  BYTE[absoluteHead], dx
mov dx, WORD [bpbSectorPerTrack]
mul BYTES [bpbNumberOfHeads]
xor ax, ax
div dx

Re: Mul Confusion

Posted: Mon Aug 08, 2011 11:32 am
by Combuster
mul cx ;Why multiply by cx? Why not ax?
As far as I know, a multiplication requires two numbers. What is multiplied by cx? Right, it's the ax you can't see.

Do you have a copy of intel manuals, volume 2? You should read it.

Re: CHS and LBA Confusion

Posted: Mon Aug 08, 2011 1:54 pm
by sds2017
Thank you for your reply and I'll look into intel manuals, volume 2 but, I don't understand what your explanation mean ""Right, its the ax you can't see". I thought your supposed to multiply ax by cl but, instead the multiply cl by cx. Am I right? Correct me if I'm not.

Re: CHS and LBA Confusion

Posted: Mon Aug 08, 2011 2:44 pm
by Combuster
It does just that:
mul cx ; multiply ax (implied) with cx, store result in ax:dx (again implied)

Re: CHS and LBA Confusion

Posted: Mon Aug 08, 2011 4:32 pm
by sds2017
Thanks. I just was confused. I thought that cx was multiplied by cl. I guess if you move a number into a register and you multiply that register that it applies to another register.

Re: CHS and LBA Confusion

Posted: Mon Aug 08, 2011 10:08 pm
by Brendan
Hi,
sds2017 wrote:The formula to convert CHS to LBA:

Code: Select all

CHS to LBA
Formula    
    LBA = (cluster - 2 ) * sectors per cluster
And here the code:
          
          sub     ax, 0x0002                          ; subtract 2 from cluster number
          xor     cx, cx
          mov     cl, BYTE [bpbSectorsPerCluster]     ; get sectors per cluster
          mul     cx                                                   ;Why multiply by cx? Why not ax?
That doesn't convert CHS into LBA. It converts a FAT "cluster number" into an LBA.

"mul cx" actually does "dx:ax = ax * cx", and gives a 32-bit unsigned integer (in DX:AX) as a result.
sds2017 wrote:

Code: Select all

LBA to CHS
Formula:
      absolute sector 	= 	(logical sector / sectors per track) + 1
      absolute head   	= 	(logical sector / sectors per track) MOD number of heads
      absolute track 	= 	 logical sector / (sectors per track * number of heads)
That formula looks wrong to me. It should be:

Code: Select all

      absolute sector 	= 	(logical sector MOD sectors per track) + 1
      absolute head   	= 	(logical sector / sectors per track) MOD number of heads
      absolute track 	= 	 logical sector / (sectors per track * number of heads)
You can rearrange it like this:

Code: Select all

      quotient1 = logical sector / sectors per track
      remainder1 = logical sector MOD sectors per track
      absolute sector = 	remainder1 + 1
      quotient2 = quotient1 / number of heads
      remainder2 = quotient1 MOD number of heads
      absolute head = remainder2
      absolute track =  quotient2
Note that the DIV instruction gives you the quotient and the remainder (which is why I did the "quotient1" and "remainder1" thing - you get both from one division). For e.g. "AX = DX:AX / divisor; DX = DX:AX MOD divisor".

Here's the original code with comments added:

Code: Select all

Input:
 AX = LBA address (why not DX:AX?)

Code:
    LBACHS:
          xor     dx, dx                          ;dx:ax = LBA address                   
          div     WORD [bpbSectorsPerTrack]       ;dx = LBA address MOD sectors per track
                                                  ;ax = LBA address / sectors per track
          inc     dl                              ;dl =  LBA address MOD sectors per track + 1
          mov     BYTE [absoluteSector], dl       ;Sector = LBA address MOD sectors per track + 1
 
          xor     dx, dx                          ;dx:ax = LBA address / sectors per track
          div     WORD [bpbHeadsPerCylinder]      ;dx = (LBA address / sectors per track) MOD heads per cylinder
                                                  ;ax = (LBA address / sectors per track) / heads per cylinder
          mov     BYTE [absoluteHead], dl         ;Head = (LBA address / sectors per track) MOD heads per cylinder
          mov     BYTE [absoluteTrack], al        ;Track = (LBA address / sectors per track) / heads per cylinder
          ret
You can see that it does implement the corrected version of the formulas (but didn't implement the original/wrong version of those formulas).


Cheers,

Brendan

Re: CHS and LBA Confusion

Posted: Tue Aug 09, 2011 3:44 am
by egos
To use 32-bit LBA for division you should imlement "double division" operation because the quotient after "single division" can be > 65535.
Brendan wrote:That doesn't convert CHS into LBA. It converts a FAT "cluster number" into an LBA.
It's "LBA" within data area. Don't forget about hidden sectors, reserved sectors, FATSize*FATs sectors and root sectors (FAT1x).

sds2017, there is no reason to convert CHS to LBA at all.

Re: CHS and LBA Confusion

Posted: Tue Aug 09, 2011 6:11 pm
by sds2017
Thank you now I completely understand it.