18

The Intel 8086 supported unaligned loads and stores of 16-bit data, e.g. mov ax, foo was guaranteed to work even if foo was odd.

What did this cost, in terms of performance and chip area, compared to an alternative architecture that would have been the same except for unaligned access being a trap or undefined behavior?

To be clear, I'm not talking about the dynamic behavior of code. On the actual 8086, access was still faster if the pointer did happen to be even. I'm asking, suppose all your pointers for word access were actually even, how much bigger and slower was the chip made by having to support the possibility that some of them could have been odd?

My first thought is that obviously a load/store circuit that doesn't need to take into account the possibility of unaligned access (and be ready to do the complicated fallback routine of two accesses and splicing the parts together) must clearly be simpler, therefore smaller and faster, then one does need to take into account this possibility.

On the other hand, the instruction decoder needs to support unaligned access anyway.

On the third hand, that might not be relevant here; the instruction decoder is probably a completely separate circuit that doesn't share parts with the data load/store circuitry.

Which points back to the conclusion that the chip could have been smaller and faster if it didn't support unaligned access.

Then again, maybe the test for the fallback case, wasn't a bottleneck in cycle time? In that case, maybe it only cost chip area?

Or maybe it was an extra microcode stage? In that case, every aligned access would have been at least one full clock cycle slower, just to support the possibility of unaligned access?

3
  • 5
    I don't have an answer to the asked question, but the 8086 separates the Execution Unit from the Bus Interface Unit and thus the 8088 has a different BIU. BIU anyway fetches code into Prefetch Queue and the EU executes code from the PQ. On 8086 the BIU can fetch code in 16-bit words (except if the jumped address is odd it fetches 8-bit byte first). So only 16-bit data accesses into odd addresses needs to split into two 8-bit byte accesses in the 8086 BIU. The 8088 having a 8-bit bus needs to access code and data in 8-bit units so 16-bit word accesses need to be splitted anyway.
    – Justme
    Jul 5 at 20:19
  • 9
    One of the design goals for the 8086 was to allow machine translation of existing 8080 and 8085 code. This required unaligned access.
    – dan04
    Jul 5 at 22:30
  • @dan04 The final killer argument :))
    – Raffzahn
    Jul 5 at 23:33

1 Answer 1

16

The Missing Angle

It feels a bit like the question misses the most important point about the whole 8086 project over discussing implementation details:

8080/85 compatibility

The 8086 was intended as a stop-gap measure for CPU sales until the all-solving i432 family was done(*1). One should not forget that Intel's (*2) main customer base was what now is called embedded systems (*3). Back then like today, systems grew faster than resources and 8080/85 family users were asking for a follow-up satisfying that need without rewriting all code.

The 8086's main selling points were

  • More memory than the 8080/85
  • Close compatibility to the 8080/85

That close compatibility is not only visible in the 8086 register set but also in the instruction formats - no other 16-bit CPU 'wasted' so much code space for single-byte opcodes. With few exceptions all 8080 instructions had 1:1 8086 counterparts, enabling static and mostly automatic translation.

For code, address alignment isn't a big deal (*4), but it is for data. Data addresses and their relation are deeply engraved in code - with assembly (maybe) even more. And that is where a requirement for word alignment would hit hard: The 8080/85 does not know such thing as word alignment and no programmer would have cared until that point.

Anyone who ever had to change structures that are tightly fit (*5) to memory (and storage) will know how much of a work that can be. Changing data structures may be equal to a complete rewrite - which would likely push towards switching to a different, more promising CPU such as 68k.

As a result it was a mandatory requirement for the 8086 to work with word data at odd addresses.

In addition it must be possible to read byte values from odd addresses without selecting the even part - not at least to read an 8 bit port at an odd address without selecting another at the corresponding even as well.

With that, it is no question if it could have saved space or not.

What Cost

With a 16-bit bus and the ability to read high and low byte independently, the whole hardware needed when reading is just two simple multiplexers to route the data:

  • one to load the first byte read from low address delivered on D8..15 to a data latch holding the low value during the first read
  • the second to do the the same for the second byte from the next address, provided on D0..D7

The first one must be present anyway to allow reading byte values from odd addresses - and of course from 8-bit ports at such.

For writing it's the same, just the other way around. So the additional hardware need is four 8-bit multiplexers. That's the very basic stuff of any data path. Make it a hundred transistors at most - not much compared to the 20-30k transistors an 8086 features. Even less as I would assume those connections exist anyway.

The Questions

What did this cost, in terms of performance and chip area?

Well, performance-wise it's of course the need to do two memory accesses instead of one, slowing that instruction down by four additional cycles. Chip-wise I would say none at all (see above).

compared to an alternative architecture that would have been the same except for unaligned access being a trap or undefined behavior?

Undefined is a bad idea and trap does for sure add more circuitry.

My first thought is that obviously a load/store circuit that doesn't need to take into account the possibility of unaligned access must clearly be simpler

Not really, as it still needs to support single-byte reads/writes to either half.

On the other hand, the instruction decoder needs to support unaligned access anyway.

Yes, but not how you think: The instruction stream is a byte stream, thus the prefetch logic does operate on byte level but the queue works on word level(*6).

Which points back to the conclusion that the chip could have been smaller and faster if it didn't support unaligned access.

No, the chip would neither notably smaller nor faster, beside the additional memory cycle that is.

In that case, every aligned access would have been at least one full clock cycle slower, just to support the possibility of unaligned access?

No, the additional memory cycle is only done if it's at an odd address. That would also be true if it was controlled by microprogram - which it wasn't.


*1 - Ken Shirriff just recently added a well written overview of he 80960 history, including many i432 references.

*2 - And all other microprocessor manufacturers.

*3 - GP computers were maybe more visible but puny in value compared to the many millions of CPUs sold for control application. Street lights, elevators and fridges still outnumber GP computers by far - or as

*4 - As long as it still fits inside the address space - which the 8086 duly expanded.

*5 - Just imagine the simple case of a structure with byte and word values mixed in between - oh, and have it having an odd length but being used in an array :))

*6 - Meaning that fetches from odd addresses, like after a jump, get done as a byte, while fetched words get split into bytes before being rearranged into words again - but now instruction aligned. It's one of the parts that made the later (!) creation of the 8088 easy (*7). Ken Shirriff goes into details when discussing prefetch on the 8086

*7 - Which Stephen Morse, the 8086's original creator, had not in mind. The 8088 was done by an independent team in Israel after the 8086 was finished.

9
  • 1
    @MarkMorganLloyd The 486 has a nice sizeable bus interface, allowing transfer for anything from 8 to 32 bit. Long ago I made a fun 486 card for the Apple II+ using that feature :))
    – Raffzahn
    Jul 6 at 12:28
  • 1
    :-) As also demonstrated by the project I cited. I was really quite surprised, after the "fun" that the very experienced chap who did the design for us had with the '386. Jul 6 at 12:31
  • 1
    Splitting unaligned word reads into a pair of byte accesses requires having a limited-function ALU in the bus interface unit that otherwise wouldn't need to be there. I wouldn't be at all surprised if the 8088/8086 use the same ALU to perform segment/offset arithmetic as to increment the address between bytes of a word, but there would be no need to be able to route the bottom 4 bits of the address through that ALU without support for processing a word access as a pair of byte accesses.
    – supercat
    Jul 6 at 14:45
  • 1
    If one were adapting a 16-bit platform that didn't allow unaligned reads for use on a narrower bus, only the bottom bit of the address could change when accessing both halves of a word. I suppose I'm not positive, on the 8088 or 8086, whether a word access at 0x1000:0xFFFF would hit physical addresses 0x1FFFF and 0x10000 or 0x1FFFF and 0x20000. If the latter, that would strongly imply that the same ALU was used for segmentation and word splitting, meaning that the latter only required extending the carry chain by 4 bits.
    – supercat
    Jul 6 at 14:51
  • 1
    Third choice for what to do when presented with a read of an odd address: read the corresponding even address. In encountered a processor documented to do this.
    – Joshua
    Jul 6 at 17:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .