6

OK, this question sounds simple but I am taken by surprise. In the ancient days when 1 Megabyte was a huge amount of memory, Intel was trying to figure out how to use 16 bits to access 1 Megabyte of memory. They came up with the idea of using segment and offset address values to generate a 20 bit address.

Now, 20 bits gives 2^20 = 1,048,576 locations that can be addressed. Now assuming that we access 1 byte per address location we get 1,048,576/(1024*1024) = 2^20/2^20 Megabytes = 1 Megabyte. Ok understood.

The confusion comes here, we have 16 bit data bus in the ancient 8086 and can access 2 bytes at a time rather than 1, this equate 20 bit address to being able to access a total of 2 Megabyte of data right? Why do we assume that each address only has 1 byte stored in it when the data bus is 2 bytes wide? I am confused here.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
quantum231
  • 2,420
  • 3
  • 31
  • 53
  • For a developer an address can point to a memory block of arbitrary size, correct. I assume, processor model requires a minimal block loadable to a register (byte, right?) to be uniquely addressable. – mikalai Aug 27 '13 at 20:55
  • hmm, could you kindly elaborate? I was just totally surprised that the addressable word is not 2 bytes like the data bus width. I really did not expect. I did the calculation a few times and got 2 megabytes, than I realized that the addressable word must be 1 byte long so 20 bits give us 1 megabyte exactly. I am wondering why no body has responded yet, – quantum231 Aug 28 '13 at 07:43
  • Probably, you shouldn't involve bus here. I suspect that you calculated something like 'bandwidth': having 2-bytes-wide bus you can transfer twice than 1-byte-wide bus. But bus still has nothing to do with addressing. You should be able to address a certain byte. For example you have address #0 pointing to word 'AB' and #1: 'CD'. How can you say to CPU 'load byte 'B' to AX" with your word-based addressing? What if I want to address a dword, or a quad? – mikalai Aug 28 '13 at 07:53
  • In a way, the 8086 was a transitional hybrid processor designed to excel at both great new 16-bit code, as well as then-current 8-bit code that might be ported to it. That's why it had a full complement of 8-bit-only instructions. Also, Intel had a variant called 8088, which had an 8-bit bus instead of 16-bit, which would allow people to make cheaper machines that used then-prevalent components. The IBM 5150 (the original PC) shipped with an 8088, not an 8086. So, it needed to support 8-bit addressing regardless of its optimal word size (16-bit). – Euro Micelli Sep 30 '13 at 18:54
  • Answering narrowly just your question: because the 8086 uses 8-bit addressing, not 16-bit. Even when using the 8086 with its full 16-bit data bus (vs. the 8088 which had an 8-bit bus), the addresses point to individual bytes, not 16-bit words. – Euro Micelli Oct 02 '13 at 04:15
  • wow finally, I see, it does make little sense if with a 16 bit data bus and 16 bit addressing we are just going to address single bytes when the data bus can have 2 bytes at a time. – quantum231 Oct 09 '13 at 08:41
  • Having designed an 8086 based system myself, I have to give full credit for asking a question like this, because it's about the first thing I asked myself! The answer is not trivial but I've tried my best below... – Matthew Millman Sep 17 '14 at 10:57

2 Answers2

5

It is very important to consider the bus when trying to understand this. This is probably more of an electrical question than a software one, but here is the answer:

For 8086, when reading from ROM, The least significant address line (A0) is not used, reducing the number of address lines to 19 right then and there.

In the case where the CPU needs to read 16 bits from an odd address, say, bytes at 0x3 and 0x4, it will actually do two 16-bit reads: One from 0x2 and one from 0x4, and discard bytes 0x2 and 0x5.

For 8-bit ROM reads, the read on the bus is still 16-bits but the unneeded byte is discarded.

But for RAM there is sometimes a need to write just a single byte, this gets a little more complex. There is an extra output signal on the processor called BHE# (Bus high enable). The combination of A0 and BHE# are used to determine if the write is an 8 or 16-bits wide, and whether or not it is at an odd or even address.

Understanding these two signals is key to answering your question. Stating it simply as possible:

8-bit even access: A0 OFF, BHE# OFF

8-bit odd access: A0 ON, BHE# ON

16-bit access (must be even): A0 OFF, BHE# ON

And we cannot have a bus cycle with A0 ON and BHE# OFF because an odd access to the even byte of the bus is meaningless.

Relating this back to your original understanding: You are completely correct in the case of memory devices. A 1 megabyte 16-bit memory chip will indeed only have 19 address lines, to that chip, 16 bits is a byte, and in effect, they do not physically have an A0 address input.

... almost. 16-bit writable memory devices have two extra signals (BHE# and BLE#) which are connected to the CPU's BHE# and A0 respectively. This so they know to ignore part of the bus when an 8-bit access is under way, making them hybrid 8/16 bit devices. ROM chips do not have these signals.

For the hardware unenlightened, this is a fairly complex area we're touching on here, and it does get very complex indeed in terms of performance considerations and in large systems with mixed 8 and 16 bit hardware.

It's is all explained in fantastic detail in the 8086 datasheet

Matthew Millman
  • 512
  • 5
  • 13
1

It's because a byte is the 'atom' in memory addressing and the code must be able to access all the individual bytes in the address space. really a matter of software and compatibility with 8-bit existing software back then.

This too may interest you: How a single byte of memory is accessed by CPU in a 32-bit memory and 32-bit processor

Community
  • 1
  • 1
Alireza
  • 4,976
  • 1
  • 23
  • 36