7

The 8088 provided an address space of one megabyte.

The IBM PC allocated that address space as 640K RAM (not that the 5150 could physically take that much, but the address space was allocated) followed by 384K everything else (BIOS ROM, video memory, other memory mapped expansion cards etc.)

It has been argued that this was a mistake, because when the foreseeable need for more address space was satisfied, that upper 384K left a hole in the address space, with RAM before and after it. That it would've been better to put the other stuff at the beginning of the address space, followed by the 640K RAM.

But as far as I can see, it doesn't really matter. If we fast-forward to the 386, where a typical system has several megabytes of RAM, it seems to me that it should be possible to provide all of that in a linear chunk starting at one megabyte and also mirror the first part of it into the first 640K, but in any case, I don't see that the difficulty is really affected by which way around the first megabyte is mapped.

Why was the arrangement chosen with RAM in the first part of the address space? Was it a purely arbitrary choice, or was there some technical reason?

2
  • 11
    The reset vector for the 8088/8086 is at 0xFFFF0, which is just below 1MB. So you'd have to have some ROM there to be able to boot up.
    – brhans
    Apr 7, 2019 at 2:58
  • 6
    Also, the interrupt vector table in the 8088/8086 started at 0x00000. While you can shift it around on later x86 models, having no RAM there would break compatibility with lots of legacy DOS programs. So you need RAM there, no matter if it's mirrored or not mirrored.
    – dirkt
    Apr 7, 2019 at 6:48

2 Answers 2

12

[This Answer focuses on the reason why RAM at low address and ROM at high address, as the usual ramblings about the 640Ki border have been made in other places and amasse (*1)]

Why was the arrangement chosen with RAM in the first part of the address space?

It's the way Intel laid out the 8086.

The CPU starts execution at FFFF:0000, thus ROM had to be up there.

Intel learned from the success of the 8080 (and follow up Z80) as CPU for general purpose computers with variable programming (aka PCs). Here it is a great plus if entry points / vector tables can be set up and changed during run time. >The basic 8080 concept with restarts in low memory (Reset at 0000 and so on) works great for an embedded system. But for a computer it must be possible to change them from ROM configuration to some value the OS or a loaded user program needs. But at the same time, at least the entry for reset must be in some ROM (like) to make the machine boot at all.

Handling that problem for an 8080/8085/Z80 ended up in three solutions:

  1. ROM at 0000h, each and every call to a restart gets first processed by ROM routines and at some point, if at all handed over to loaded (user/OS) code

  2. ROM at 0000h, all calls (*2) get handed to a user pointer table via a jump indirect stub of various kind

  3. ROM at 0000h, much like the first, but it gets replaced by RAM at runtime, enabling variable handling routines.

Any of these either limits functionality, adds processing time or needs additional hardware. Uncool.

For the 8086, its designers tried to break from these limits by separating Reset which always needs to be handled in ROM from all other exceptions to allow dynamic setup. Thus the CPU starts executing with segment FFFFh, offset 0000h while the vector table is located at Segment 0000h (*3) offset 0000h. As a result no hardware for switching out ROMs was needed, while at the same time the shortest possible code path for (variable target) exceptions was enabled. Lesson learned (*4,*5).

Bottom line: Never forget that the first microprocessors were not designed as core of a general purpose computers, but to make embedded controllers.


*1 - Can't hold my inner Nerd back: Come on, there has to be RAM and ROM in a system, and I/O (like video) is usually something to be put in-between. Heck, even the template for the IBM PC, the Apple II, made by the great Woz did it that way ... it even features a similar split 6:2 for RAM vs. I/O and ROM. For the PC it's 5:3.

*2 - Except Reset which still gets processed to some point in ROM

*3 - It's important to see this as segments, as that's not only the way it is implemented, but as well the (original) intended upgrade path for later CPUs.

*4 - In addition the concept was changed from restarting at the calculated location as the 8080 did, to address pointers (like Motorola already had) to be used with an indirect jump. After all, 4 bytes couldn't hold much code - already making it indirect resulted in a subsequent table and jumping twice.

*5 - Motorola as well changed when going 16 Bit. The location their a vector table from top memory down to zero

6
  • Bo mention of CP/M, and how its BIOS and BDOS were stored in upper RAM? You had to regen CP/M when you added RAM to a system so BIOS & BDOS would be at the new top of RAM.
    – RonJohn
    Jan 10 at 4:30
  • *5 the 68000 has the added difficulty that the reset vector is at 0 which complicates circuitry. At least on the Atari ST does a circuit blend in 8 bytes of ROM at reset time for a limited number of cycles so that the machine can at least bootstrap and jump into the ROM at $FC0000 (ST) or $E00000 (STE/TT). Jan 10 at 8:29
  • @PatrickSchlüter hen again, it's exactly the same "complication' the 8080 featured since inception. But yeah, another point that makes the 8086 a very handy designed CPU.
    – Raffzahn
    Jan 10 at 10:52
  • @RonJohn That 'feature' is not CPU related, but CP/M missing a relocation phase during boot. As a result it had to be relocated 'manually'
    – Raffzahn
    Jan 10 at 10:55
  • I didn't say it was. The PC was designed with the expectation of running CP/M-86, so it's of course you design the memory map in such a manner.
    – RonJohn
    Jan 10 at 17:14
3

The 5150 used 8088 CPU which only had 1024 KB of address space. When 5150 was designed, the 286 did not exist yet so there was no future compatibilities to think of. As the 8088 booted from the end of memory, ROM had to be put there. And as interrupt vectors are at start of memory, something had to be there so it was most flexible to start RAM from there.

So against what you say that the 384 KB left a hole in the address space, it did not. On a 8088 and 8086, that is the end of the 1024KB of memory space that can be accessed.

7
  • 2
    While I basically agree with this, the 80286 (and 80186) were almost certainly well into design by the time the 5150 was introduced. Arguably, if IBM wanted to, they could have gotten (and perhaps did) get more information from Intel about future plans in order to build the 5150 with more future compatibility. However, the 5150 was actually a low-end machine (8088 instead of 8086, but also started with low RAM capacity motherboard, no standard hard drive until the XT (2 years later and well after the introduction of the 286). They just didn't anticipate the huge success of the 5150. Apr 7, 2019 at 14:55
  • 2
    Consider also that the design of the 5150 was fairly engineering-resource constrained: they had fairly aggressive deadlines (which is not unusual for any commerical product) and engineering work to meet those deadlines was obviously higher priority than engineering work related to future compatibility. It's hardly the first computer that used shortcuts compromising future expanadability in order to meet current-day deadlines.
    – cjs
    Aug 14, 2019 at 7:32
  • 2
    Alternatively: Serious design for the PC started around August 1980, less than 18 months before the release of the '286. By that point the general idea of processes using virtual addresses mapped to arbitrary physical addresses via segment descriptors would have been nailed down, and IBM as a large customer would almost certianly have been privy to this information. So it could well be that, looking forward, they felt that within a half decade or so large applications wouldn't be using the current memory map so it wouldn't be an issue.
    – cjs
    Aug 14, 2019 at 8:11
  • It would have been fairly simple to design hardware for an 80286-based computer with a contiguous region of up to 8MB of RAM at 0x4000000, and with the first 640K of address space mapped as a shadow to the start of that storage. On the flip side, if Intel had wanted to allow the 80286 to access extra memory within the context of a general-purpose 8086 program, they could have offered a mode where segment values below 0xC000 would be treated in "classic" fashion, those 0xC000 and up that were multiples of 0x0800 would be treated in classic fashion but displaced up 15MiB, and the rest...
    – supercat
    Jan 9 at 16:11
  • 1
    Most of the code I've seen that uses physical addresses in the 0xC0000-and-up range uses segment values which are multiples of 0x0800, though I've not looked at EMS-related code. Thinking about it, including multiples of 0x400 or maybe 0x100 would have been better, but if the designers of EMS had advance notice of how the 80286 would work, they could ensure that they did things in a manner that would be compatible.
    – supercat
    Jan 9 at 18:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.