Why does sector-number addressing in CHS start at sector 1 and not 0?

Unfortunately, this is just how the CHS addressing scheme, popular at the time, was implemented and adopted into use. This was adopted as the official convention for IBM-compatible computers in the BIOS interrupts used for disk access, explaining why this convention is used to this day. From the ECMA-107 Standard, Volume and File Structure of Disk Cartridges for Information Interchange (this is also mentioned in the original ATA-1 specification):

6.1.3 Logical Sector Number

Each sector on a volume shall be identified by a Logical Sector Number. [...] The Logical Sector Numbers shall be assigned in an ascending sequence, beginning with 0, starting at sector 1, track 00, side 0, continuing onto track 00, side 1 (if FDC is recordable on both sides) and then to track 01, side 0, etc.

This issue is addressed in the specifications for some hard disks, where it is noted that a given logical CHS address differs from the physical CHS address location. This is further discussed in the Seagate ATA Interface Reference Manual, which contains this interesting narrative:

5.1 Logical block addressing

[...] the sectors on the drive are assumed to be linearly mapped, with an LBA 0 of cylinder 0 / head 0 / sector 1.

[...] For all translation modes, C=0, H=0, S=1 is equivalent to LBA=0. It is not possible to compute an equivalent CHS for all logical block addresses in all translation modes because this formula only works in one direction. This is because CHS addressing can’t access 1/256th of all of the possible sectors that logical block addressing can access, since there is no sector 0 in CHS.

Thus for logical CHS addressing, although the first cylinder/head indices start from a 0-based offset, and the first sector index starts from 1 (e.g. the minimum possible CHS address is 0/0/1), this does not change anything about the physical location of this sector. Think of it as the first physical sector on the disk being called "sector 1", occupying CHS 0/0/1. Indeed, the "first" element in most programming languages is 0-based, so the logical address of the sector at CHS address 0/0/1 is zero (0x00).

This makes a lot more sense logically (namely, the "zeroth" logical address being the first physical sector), as we can address the disk device as any other memory device (as each sector has a unique linear address to map it to a physical sector), thus why it makes sense for LBA to start from zero. Indeed, if we translate the CHS address 0/0/1 to an LBA, the resulting LBA will be 0x00000000 (this is why 1 is subtracted from the sector index in most CHS to LBA calculations, and why 1 is added to the index for LBA to CHS calculations).


I have tried to trace the history of CHS and the "starting with 1" sector numbering fiasco, which has caused many complications for disk-drivers writers and gave rapid rise to LBA.

CHS dates back to the days when personal computers ran on diskettes and when the BIOS was invented. This is what Wikipedia says :

The term BIOS (Basic Input/Output System) was invented by Gary Kildall and first appeared in the CP/M operating system in 1975, describing the machine-specific part of CP/M loaded during boot time that interfaces directly with the hardware.

A research into the CP/M BIOS has found the document CP/M information archive : BDOS system calls, in which sector numbers start with zero. The conclusion is that : earliest CHS schema actually used zero-based sector addresses.

One-based sector addresses were first introduced with the first IBP/PC. The document INT 13 - Diskette BIOS Services specifically says :

Most disk BIOS calls use the following parameter scheme:

    AH = function request number
    AL = number of sectors  (1-128 dec.)
    CH = cylinder number  (0-1023 dec.)
    CL = sector number  (1-17 dec.)    <--------!!!
    DH = head number  (0-15 dec.)
    DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
    DL = drive number (0=A:, 1=2nd floppy, 80h=C:, 81h=D:)
         Note that some programming references use (0-3) as the
         drive number which represents diskettes only.
    ES:BX = address of user buffer

So it was the IBM/PC that by a de-facto implementation of the BIOS has converted sector-numbering from zero-based to one-based.

Of the twelve IBM engineers assigned to create the IBM Personal Computer (model 5150), David J. Bradley developed the code for its BIOS. So he's the one who, among all its other details, decided on the parameters for the disk interrupts. We also owe to this guy together with Mel Hallerman the famous CTRL+ALT+DEL.

So the answer to the question Why does the sector count start at 1 and not 0 in CHS is :
Because David J. Bradley programmed the BIOS that way.

As to why he did it this way, this is best answered by himself. If I had to guess, I would say that he left sector zero as an addressing sector by which the driver could verify that the head was on the right track.

As disks were actually engineered so as not to require such a mechanism, and the engineers were not ready to waste one sector because of the BIOS, sector zero never came into existence. Thereafter, driver-writers were left with the need to subtract-one and add-one to sector addresses for all BIOS disk calls.