View Full Version : Memory addressing in processors < 80286

September 13th, 2010, 04:42 AM

I am wanting to document the behaviour of the 8086/8088 and the 80186/80188 when memory access exceeds a segment boundary. For example, writing a 16-bit word to offset 0xFFFF. I have found anecdotal sources around the 'net that say the following:

8086/8088: First byte will be written to offset 0xFFFF, second byte to offset 0x0000
80186: Bytes always written consecutively (first byte to 0xFFFF, second to 0x10000)
80286 and above: Exception generated (e.g. #SS or #GP)

I would rather have a more authoritative source (such as a reference to the behaviour in a processor manual) for the first two cases. Can anyone point me to any such sources?

Thanks in advance.

September 13th, 2010, 06:13 AM
It's confirmed to be the case on the 8086/8088, as some programs actually used it (for whatever reason.) That's the whole reason for the A20 enable line (http://en.wikipedia.org/wiki/A20_line) on the IBM AT, so that compatibility with quirky software could be maintained. I don't know about the 80186, though.

September 14th, 2010, 02:47 AM
I am aware of the A20 line, but my question is quite different. What you are referring to is memory address space wraparound, when the calculated physical address is beyond the limit of the CPU's address space.

What I am asking about may be best illustrated by an example. Consider this assembly language fragment:

MOV AX, 0x1000

This attempts to write a 16-bit word at 0x1000:0xFFFF. As far as I have searched, there is no documentation of the behaviour of such a write, as the most significant byte of AX will exceed the segment limit. Will it wrap around and write this byte at physical address 0x10000, or will it exceed the segment boundary and write it at 0x20000? From the 80286 upwards, such a write is illegal and will generate an exception, but given that the 8086 had no such exceptions, it must have done something.

September 14th, 2010, 05:50 AM
Oh, you're right. Guess I wasn't paying close enough attention. Unfortunately, both of my current DOS machines are 286-based, but when I get my Tandy 1000RL up and running I'll check and see what I can find out about the 8086.

September 14th, 2010, 06:54 AM
This was a cute trick when differentiating the 186 from the 86 (and V20/V30). The 8086 will wrap the segment (i.e. go to 0000 in the same segment), while the 186 would access the byte at 0000 in the next segment. The behavior is documented here (http://www.codebreakers-journal.com/content/view/229/27/). I'll have a peek at the 80186 datasheet to see if it's also mentioned there.

I think this was the result of the 80186 implementing DMA using a linear 20 bit address space (i.e. no segments). You'd think that DMA would be a completely separate implementation from the CPU logic, but it wasn't. My own personal grief with this was using an early stepping of the 186 and discovering that a DMA transfer could clobber SI or DI (took me 2 weeks of hair-pulling to find that one). I suspect that the same logic was employed in computing DMA addresses as instruction operand addresses, which would give the no-wrap operation.

Of course, on the 286 and above, this is illegal (even in V86 mode) and an exception is raised.

September 15th, 2010, 03:23 AM
Hi all,

Thanks for your assistance. I managed to find a paragraph in the 8086/8088 User's Manual that I think confirms the behaviour on the 8086

"Whenever the BIU accesses memory - to fetch an instruction or to obtain or store a variable - it generates a physical address from a logical address. This is done by shifting the segment base value four bit positions and adding the offset as illustrated in figure 2-18. Note that this addition process provides for a modulo 64k addressing (address wrap around from the end of a segment to the beginning of the same segment)."

Thanks Chuck for the Codebreakers Journal reference.

Cheers, Michael.