While the documentation for the 8088 CPU used in the original IBM PC reserved the first 32 interrupt vectors for CPU exceptions, the 8088 only made use of a few of them. When IBM designed the PC they choose to ignore this and assigned the reserved but unused vectors for their own purposes.
The original 8088 only defined exceptions for the first 5 interrupt vectors, for Divide Error, Single Step, NMI, Breakpoint, and Overflow respectively. Interrupts vectors 5 through 31 were marked as reserved in Intel's 8086 Family User's Manual:
Despite this, IBM decided to have their BIOS configure the interrupt controller to deliver hardware interrupts starting at interrupt vector 8. Since the original IBM PC only supported 8 hardware interrupts, this meant that vectors 8 through 15 were used for hardware interrupts. IBM then started assigning BIOS services starting with vector 16 (10h), to be invoked using software interrupts. In addition, vector 5 was used to implement a print screen function. Reserved vectors 6 and 7 weren't used.
Unfortunately this proved to be a mistake by IBM, as when Intel designed the 80286 they defined additional CPU exceptions in the reserved range, going up all the way to vector 13 (0Dh). This meant the IBM PC/AT, which used the 80286 CPU but also needed to be backwards compatible with the original 8088-based IBM PC, had interrupt vectors with two different purposes, one defined by the CPU and one defined by the BIOS.
In particular, having both the print screen and
BOUND violation exception using vector 5 proved to be fairly big nuisance. In theory, this shouldn't have been a problem, as any program using the the new
BOUND instruction would need to install their own interrupt handler, one that could distinguish between the two sources. In practice, however the
BOUND instruction ended up getting executed unintentionally by programs that had crashed and the default BIOS handler would then get stuck in an infinite loop of printing the screen.
The other conflicting uses for the vectors weren't as much of a problem, as exceptions 10 through 13 would normally only be generated in protected mode. A protected mode operating system didn't need to be backwards compatible and couldn't use the BIOS, so could reconfigure the interrupt controller to deliver hardware interrupts through vectors outside the reserved range.
The remainder of the CPU exceptions defined by later Intel processor were either also not normally generated by real mode code that needed to be backwards compatible or handled by default BIOS handlers that could properly distinguish between sources.