The 640k barrier
One of the biggest limitations of MS-DOS was that programs could only use 640 kilobytes of memory. This was because the addressable space of the 16-bit 8086-8088 was only one megabyte, and the other 360K supported the operating system.
The 8086 chip had four segment registers all with special purposes. It had a 16-bit program counter, a 16-bit ALU (arithmetic and logic unit), four 16-bit general purpose registers, and some 16-bit index registers. It also has four 16-bit segment registers. The 8086 performs all computation and data transfer in 16-bit arithmetic, with one exception: immediately before gating an address onto the external address bus, it selects one of the segment registers, shifts it four bits to the left, and adds the address to it, using 20-bit arithmetic.
Intel’s documentation describes this architecture as a programming convenience. They advertise it along the lines of “here’s your code, here’s your data, and each is neatly stored in its own segment.” Students of computer science also like segmented architectures for various OS design reasons.
Actually programming this machine is a different story. In fact, it’s a total nightmare. Nothing can actually just be “addressed” directly. Instead, you have to rely on workarounds, such as if you have more than the allowed amount of data, you have to reload segment registers on the fly. This means, among other things, that there’s no good way to index sizable arrays.
This Rube Goldberg approach would have faded into history if IBM hadn’t chose the 8086 for its PC platform in 1980. Other vendors cloned the IBM PC, and the chip quickly obtained 90% market share with both hardware vendors and software vendors. Everyone had to learn to deal with its limitations.
It didn’t take long before hardware developers realized that they needed better chip architecture. The solution was the 80286. This chip had an external address bus of 24 bits, but it still had to manipulate segment registers, each limited to 64 kilobytes. In part, the 80286 was intentionally limited by the need to run existing programs.
The result was a hybrid that could handle all the bells and whistles of new technology, or it would run in a crippled mode to remain backward-compatible with old programs. Speed increases came from faster clock speeds and 16-bit data busses. However, the programmer was still limited to the same 1 megabyte address space for DOS-based programs.
Intel intended for the 80286 to provide a path for upward evolution of PC systems. They hoped that its DOS compatibility would allow it to gain acceptance, and that once there was a sufficient installed base of 80286 processors, software developers would begin writing operating systems and programs that used its advanced features. Instead, PC clone vendors used it as a high-performance 8086.
Like the 80286, the 80386 had a segmented architecture and two modes: one for old programs and one for new ones. The segmentation scheme was even more complex than that of the 80286. It did, however, allow 32-bit segment offsets, so a single segment could be up to four gigabytes. This allowed a programmer to define a single segment that covered all available memory. It also allowed indexing into arrays that larger than 64K bytes. In practice, though, the capabilities of the 80386 were not used much more than those of the 80286.