Width of PC Memory

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
lukassevc
Posts: 20
Joined: Wed May 29, 2019 2:56 pm
Libera.chat IRC: lukassevc

Width of PC Memory

Post by lukassevc »

Hello,

I was trying to figure out what's the width of PC memory because when I read that the real mode can access only 1 MiB of memory and I was confused since the width of the data bus is 16 bits, which means that it should be correctly MiW or whatever, where W stands for word as 16 bits ( for 32 bit CPU 4 GDW, where DW stands for double word, and accordingly for the 64 bit CPU it should be 16 EiQW where QW is quad-word ) or every memory size should be multiplied correctly for the data width i.e. you have in reality 2 MiB since we have 2 bytes per address so I just multiplied the address size by the number of bytes of the data bus? And if so, how are instructions stored in the memory? For example the MOV instruction, are the opcode and the parameters stored on multiple addresses? And if so, what's the value of the other unused bits in the let's say QW opcode? Is it just 0? And when I read from the drive is it stored on multiple addresses by 1 byte or by a QW and occupying much less address space? And when I use the lods- instructions, it reads just the lower N bits of the whole QW? And does it mean that in the PM mode I can simply store whole UTF-8 character on a single memory address?

Thanks for you answers and time!
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Width of PC Memory

Post by iansjack »

The processor can read/write single bytes from memory, so an array of bytes is the appropriate view of memory to use. Opcodes (in the x86 family of processors) are of variable width. Some are only one byte.

(Some instructions can deal with individual bits, but these are the exception rather than the rule, so it wouldn't really make sense to consider memory as an array of bits.)
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Width of PC Memory

Post by bzt »

iansjack wrote:The processor can read/write single bytes from memory, so an array of bytes is the appropriate view of memory to use. Opcodes (in the x86 family of processors) are of variable width. Some are only one byte.
I think he meant the address space size, not the variable size.
lukassevc wrote:I read that the real mode can access only 1 MiB of memory and I was confused since the width of the data bus is 16 bits
Nope, the width of the data bus is 20 bits, also called address space size, do not confuse with variable width (which can be 8 or 16 bits in real mode). That's true that you have 16 bit wide registers, but two registers take part in calculating an address, a segment and an offset.

See memory addressing.

Code: Select all

+----------------+
|15             0|0000          segment register, shifted 4 bits
+----------------+
    +----------------+
0000|15            0 |          offset register
    +----------------+
<-------------------->          total width 20 bits, that's 1MiB
Addresses bigger than that wrap over (meaning 1M + 1 is the same as offset 1, because most significant bits doesn't work). To turn this off, and get the entire 32 bit address space (or 36 with PAE and 48 in long mode) you have to enable the A20 line thus extending the data bus width. This does not change the variable width in any way, that remains the same (and only changes with the instruction encoding being prot mode or long mode, allowing 8, 16, 32 or 64 bits)

Cheers,
bzt
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Width of PC Memory

Post by iansjack »

bzt wrote:I think he meant the address space size, not the variable size.
No. I read the question as to why we talk about memory in terms of MB rather than MWords, or anything else.

The confusion between the size of the data bus and the address bus is a secondary matter. I answered the question of why we talk about memory sizes in bytes rather than, words, double words, quad words, etc.

"Variable width" is not really a concept that I would think is relevant here. Variables can be any width that you think of, from a single bit to many hundreds of bytes. This is totally independent of the architecture of the underlying processor.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Width of PC Memory

Post by bzt »

The OP is confused a bit about these, I agree.
iansjack wrote:
bzt wrote:I think he meant the address space size, not the variable size.
No. I read the question as to why we talk about memory in terms of MB rather than MWords, or anything else.
He used the words "data bus" and said "width of the data bus is 16 bits", that's why I thought he meant that.
iansjack wrote:"Variable width" is not really a concept that I would think is relevant here. Variables can be any width that you think of, from a single bit to many hundreds of bytes. This is totally independent of the architecture of the underlying processor.
No it's not independent. Some architectures can only access memory in words at aligned addresses only, but this isn't the case with x86 I give you that. For x86 it doesn't matter.

(Interesting thing: ARM without MMU mandates word sized read/writes at word aligned addresses, otherwise the CPU raises an align fault. With MMU turned on, it works just like the x86, you can access any byte, word, dword, etc. at any address and you won't get faults.)
lukassevc wrote:every memory size should be multiplied correctly for the data width i.e. you have in reality 2 MiB since we have 2 bytes per address
Changing the variable width does not change the address size. If you access memory by bytes, you can use any address. But if you access it as words, there's no multiplication, instead the lower bits must be all 0s thus giving a word aligned address. That's for restricted architectures (m68k, ARM without MMU etc.), on x86 you can use those bits, and you can access a qword (8 bytes) at address 7 for example.

Cheers,
bzt
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: Width of PC Memory

Post by nullplan »

bzt wrote:Nope, the width of the data bus is 20 bits
No, that is (was) the address bus. The data bus in the original PC was 8 bits. That was the reason why IBM chose the 8088 as CPU, which is an 8086 with an 8-bit data bus. It was the XT with the 286 CPU that pioneered a (somewhat) 16-bit data bus in PCs.
bzt wrote:The OP is confused a bit about these, I agree.
Glass house, meet stone.
Carpe diem!
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Width of PC Memory

Post by bzt »

nullplan wrote:Glass house, meet stone.
Yeah, it would be better if people would just simply use the original phrases for these, like "címtér" and "szóméret" and there would be no confusion at all :-P John von Neumann used so clear and descriptive names for everything, it's too bad those were translated into misleading English words...

Cheers,
bzt
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: Width of PC Memory

Post by Schol-R-LEA »

OK, let's try to break it down in detail.
lukassevc wrote:I was trying to figure out what's the width of PC memory because when I read that the real mode can access only 1 MiB of memory and I was confused since the width of the data bus is 16 bits, which means that it should be correctly MiW or whatever, where W stands for word as 16 bits
The real reason is simple: because memory is addressed in bytes, not system words (more on the term 'words' shortly). Each address, regardless of the width of the address space, points to a specific byte in memory.

This means that adding one to a pointer - again, regardless of the size of the variable being pointed to - means it is pointing to the next byte in memory.

These bytes may be aggregated into larger variables, each comprised of two or more bytes, but the addresses still are to the individual bytes within that variable.

So in order to walk through an array of bytes using a pointer (rather than an index), you would add one to the pointer; to walk through an array of 16-bit values, you would add two to the pointer; to walk through an array of 128-byte data structures, you would increment the pointer by 128; and so forth.

Compilers for languages such as C will automatically adjust how much to increment a pointer by, which is what is referred to as 'pointer arithmetic'. It is simply hiding the implementation details to make things easier.

You also have matters of byte alignment, where certain variables must (or at least should) be aligned on addresses which are even multiples of 2, 4, 8, etc. in order to be usable at maximum performance. This is unrelated to the address width or data bus width, however.

Note regarding terminology: outside of the world of x86, 'word' refers to the 'system word', that is to say, the largest value a CPU can hold in a general-purpose register; thus, for a 32-bit ARM, a 'word' is 32 bits, while for a 64-bit ARM, a 'word' is 64 bits. The use of 'word', double-word', 'quad-word', in x86 usage is something of an artifact of the development of 16, 32, and eventually 64 bit models of the x86 line. None of this really changes the fact that the memory is addressed by individual bytes on all modern-day machines (there were systems which addressed by words longer than one byte in the past, but none are in regular use today).

As an historical aside, the size of a byte as eight bits is itself a convention, first adopted by IBM in the 1960s but becoming more or less universal by the late 1970s.
lukassevc wrote:And if so, how are instructions stored in the memory? For example the MOV instruction, are the opcode and the parameters stored on multiple addresses? And if so, what's the value of the other unused bits in the let's say QW opcode? Is it just 0?
This is going to depend on the Instruction Set Architecture (ISA), but for x86, instructions are of variable width, so the CPU has to decode the first byte in order to know how many other bytes it needs to fetch in order to decode the whole instruction. On older implementations of the ISA (which fetched directly from memory), this made it relatively slow to decode multi-byte instructions, but modern Intel and AMD CPUs not only cache the instruction stream, and pipeline the instructions to allow for complex decoding, they also use several clever tricks to break down instructions into simpler forms which are what actually get run.

For the MOV example, that mnemonic actually maps to several different instructions, which start with one of several different and distinct opcodes. The shortest of these is a single byte; others may be considerably longer. The CPU has to then fetch the rest of the instruction bytes, if any, in order to know things such as addresses.

This is in contrast to most other modern CPU ISAs, the majority of which are designed on the RISC (Reduced Instruction Set Computer) philosophy. One of the tenets if RISC is to use fixed-width instructions in order to simplify instruction decoding. Generally, RISC CPUs will have an instruction width of 32 bits (4 bytes) across the board, even for instructions operating directly on memory (which they general restrict to load and store operations, with everything else being done in registers - which is part of why most RISC designs have a register set of at least 16 general-purpose registers).
lukassevc wrote:And when I read from the drive is it stored on multiple addresses by 1 byte or by a QW and occupying much less address space?
Peripherals such as disk drives are a separate subject from the ISA and memory addressing, really - it all depends on the device and how it is mapped into either I/O space or memory (or both).

In the case of a disk drive, those are block devices - they always read a full block into memory, which generally means at minimum 512 bytes (one standard disk sector). Even if all you need is a single byte, it will always buffer at least one full block.
lukassevc wrote:And when I use the lods- instructions, it reads just the lower N bits of the whole QW?
No, it operates on the number of bytes indicated by the word size character (b/w/d/q), no more, no less.
lukassevc wrote:And does it mean that in the PM mode I can simply store whole UTF-8 character on a single memory address?
No, because each address is always one byte, and a UTF-8 character could be two or four bytes long.
Last edited by Schol-R-LEA on Thu Mar 11, 2021 11:21 am, edited 1 time in total.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Width of PC Memory

Post by iansjack »

nullplan wrote:It was the XT with the 286 CPU that pioneered a (somewhat) 16-bit data bus in PCs.
Just for the record:

The original PC (5150) used an 8088 processor.
The XT (5160) also used an 8088 processor.
The AT (5170) was the first IBM PC to use an 80286 processor.

The XT was, essentially, a PC with a few more expansion slots and a 5 or 10MB hard disk. Some other personal computers of that era used the 8086, most notably (in the UK anyway) the Amstrad PC1512.
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: Width of PC Memory

Post by nullplan »

bzt wrote:Yeah, it would be better if people would just simply use the original phrases for these, like "címtér" and "szóméret" and there would be no confusion at all :-P John von Neumann used so clear and descriptive names for everything, it's too bad those were translated into misleading English words...
The problem is that then, nobody except you and your countrymen could understand. English was hard enough to learn for me. I'm with Kurt Tucholsky on this: English is an easy and difficult language, full of foreign words which are pronounced wrong.

Funnily enough, when I punch címtér into Google Translate, its first guess for a source language was Slovak, in which case it means "number". But in Hungarian it means "address space". Then again, I punch the same thing into the PONS online dictionary and it fails to turn up anything. But it does tell me that címez means "to address", and so I can see a connection.
iansjack wrote:The XT (5160) also used an 8088 processor.
The AT (5170) was the first IBM PC to use an 80286 processor.
Dammit, I can never keep my XT and AT straight. Thanks for correcting me.
Carpe diem!
lukassevc
Posts: 20
Joined: Wed May 29, 2019 2:56 pm
Libera.chat IRC: lukassevc

Re: Width of PC Memory

Post by lukassevc »

Okay, in order to make this clear, I will use the pinout of the 8086 as an example, the pins A0 to A19 belong to the address bus, the pins D0 to D15 belong to the data bus and then you have those pins WR, M/IO, ... those belong to the control bus, or whatever is the name, and the question is, if we say that the 8086 can address up to 1 MiB of memory am I supposed to understand it so that it can address up to 1,048,576 points in memory, while each point is 16 bits wide due to the 16 bits of the data bus, and in that case we should say that it can access up to 1 MiW, where word means 16 bits, since one point in memory is 16 bits wide, or am I supposed to understand it so that it can literally address up to 1 MiB and since the data bus is 16 bits wide, or 2 bytes wide, we can address only up to 512 KiB? And the same thing applies to the 8088 but it puts out the data in two cycles, the first and then the second byte. And the real question is how are the data stored on a drive loaded into the RAM at the startup, is every single word (16 bits) stored on a separate address or is the BIOS somehow differentiating between 16, 32 and 64 bits long op-codes and data?

PS: I'm Slovak, and our language is very different from Hungarian.
Attachments
pin_diagram_of_8086-1-1.png
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: Width of PC Memory

Post by Schol-R-LEA »

lukassevc wrote:Okay, in order to make this clear, I will use the pinout of the 8086 as an example, the pins A0 to A19 belong to the address bus, the pins D0 to D15 belong to the data bus and then you have those pins WR, M/IO, ... those belong to the control bus, or whatever is the name, and the question is, if we say that the 8086 can address up to 1 MiB of memory am I supposed to understand it so that it can address up to 1,048,576 points in memory, while each point is 16 bits wide due to the 16 bits of the data bus, and in that case we should say that it can access up to 1 MiW, where word means 16 bits, since one point in memory is 16 bits wide, or am I supposed to understand it so that it can literally address up to 1 MiB and since the data bus is 16 bits wide, or 2 bytes wide, we can address only up to 512 KiB?
Neither. While the data bus can access 16 bits at once, it is also capable of addressing an individual 8-bit byte, and fetching only that byte. To that end, the addresses are always byte-oriented regardless of how wide a system word is.

A given 16-bit word spans two addresses, one for the low byte and the other for the high byte. Addresses always point to a specific byte, not to a word, doubleword, or quadword, as such. It is possible to point to a byte which is 'inside' a given word-aligned value the same as any other byte.

The address bus does not differentiate between the sizes of data values; while individual instructions may have a given operand size, this is a separate issue from how those operands are addressed.

As for how the address bus works, on the x86 that is a complicated subject, because of segmentation. A 16-bit address space actually is limited to 65536 values, for a total of 64KiB addressing; however, in order to give the original 8086 a 20-bit address space, the Intel designers created an arrangement of 'segments' which allows two 16-bit values to combine into a 20-bit value (just why they didn't use a full 32-bit pair is a matter of the historical size limits on addressing pins, among other things).

While it would be a bit of a digression to explain the segmentation model in detail, especially since it really only applies to real mode (while segmentation still exists in 32-bit protected mode, it is rarely used in any meaningful way, since the full 32-bit address space is available in the 'flat' memory model), suffice it to say that it comes out to an address space just a little bigger that 1 MiB.
lukassevc wrote:And the real question is how are the data stored on a drive loaded into the RAM at the startup, is every single word (16 bits) stored on a separate address or is the BIOS somehow differentiating between 16, 32 and 64 bits long op-codes and data?
As I said earlier, with block devices such as disks, the BIOS will load an entire sector or group of sectors at once - for a typical disk drive, the smallest block the BIOS can read into memory is 512 bytes.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Width of PC Memory

Post by bzt »

lukassevc wrote:if we say that the 8086 can address up to 1 MiB of memory am I supposed to understand it so that it can address up to 1,048,576 points in memory, while each point is 16 bits wide
No. Each address belongs to exactly one byte.
lukassevc wrote:is every single word (16 bits) stored on a separate address
No. Addresses address bytes, therefore word occupies two addresses as Schol-R-LEA said. That's why I wrote word access must happen on aligned addresses on strict architectures (but not with x86, that allows any address with any size).
lukassevc wrote:or is the BIOS somehow differentiating between 16, 32 and 64 bits long op-codes and data?
No. It's the CPU instruction that specifies the number of bits accessed, BIOS has no say in that matter.

Code: Select all

|0|1|2|3|4|5|7|8|9|          memory bytes, each addressed individually
  ^--                        mov al, [1]  (valid)
  ^----                      mov ax, [1]  (valid, but only because x86 does not need strict align)
  ^--------                  mov eax, [1]  (valid, but only because x86 does not need strict align)
With strict alignment it would be like this:

Code: Select all

|0|1|2|3|4|5|7|8|9|          memory bytes, each addressed individually
^--                          mov al, [0]  (valid)
  ^--                        mov al, [1]  (valid)
    ^--                      mov al, [2]  (valid)
      ^--                    mov al, [3]  (valid)
        ^--                  mov al, [4]  (valid)

^----                        mov ax, [0]  (valid)
  ^----                      mov ax, [1]  (invalid, causes fault)
    ^----                    mov ax, [2]  (valid)
      ^----                  mov ax, [3]  (invalid, causes fault)
        ^----                mov ax, [4]  (valid)

^--------                    mov eax, [0]  (valid)
  ^--------                  mov eax, [1]  (invalid, causes fault)
    ^--------                mov eax, [2]  (invalid, causes fault)
      ^--------              mov eax, [3]  (invalid, causes fault)
        ^--------            mov eax, [4]  (valid)
No matter the variable size, address will always point to bytes.
lukassevc wrote:PS: I'm Slovak, and our language is very different from Hungarian.
Hi neighbour! Yes, Hungarian is quite unique, it's totally different to any other language. Some say people think in their mother tongue, maybe that's why we come up with so many strange inventions (computer included, the one you're reading this post on is a von Neumann architecture machine).

Cheers,
bzt
Ethin
Member
Member
Posts: 625
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: Width of PC Memory

Post by Ethin »

@Op, I think your getting confused about machine addresses and disk addresses. They are distinct terms with completely different meanings.

A machine address accesses individual bytes. The word size (that is, the size of a processor register) is independent of that of the size of the data you'd access with a memory address. If you read memory address 0x1234, you will get the byte at that address, not the word or halfword or anything like that. If you load that address into a processor register (at least on a RISC machine) the bits that comprise that byte (e.g.: 8 bits) will fill the last byte of the processor register, with all other bytes and bits being zeroed (this is called sign-extension). This is in a little-endian architecture; on a big-endian architecture, the byte will fill the first 8 bits of the register, with sign-extension happening for the remaining bytes. I will assume little-endianness since that's irrelevant here.

A disk address is known as a logical block address, or LBA. An LBA varies based on what disk protocol your using and how it works. There are various protocols: ATA, NVMe, SCSI and so on. (note: this is independent of the disk controller used (e.g.: AHCI or IDE).) In ATA, an LBA is either 28 bits or 48 bits. The bit width of an LBA depends on the command. In NVMe, the size of an LBA is always 64 bits. Regardless of the size of an LBA, the disk will always return a 'block' back to you, even if you only need a single byte from that block. The block is the 'logical sector size'. The logical sector size has been, for the longest time, 512 bytes, but recently 4096-byte disks have been becoming more common. When you read a block from a disk, you will get the full block back, and you can then do what you like with it. When you write data to the disk, you will write entire blocks, not individual bytes.
lukassevc
Posts: 20
Joined: Wed May 29, 2019 2:56 pm
Libera.chat IRC: lukassevc

Re: Width of PC Memory

Post by lukassevc »

I was thinking about the problem yesterday and I think I've found the solution, for example if the 8088 wants to write 0x1234 to the address 0x00000 it writes 0x34 to the lower address, in this case it is 0x00000 and 0x12 to 0x00001, and the other hand the 8086 writes 0x1234 to the address 0x00000 since it's 16 bits wide, am I correct? And since there wasn't any other x86 microprocessor from Intel which had the data bus 8 bits long, then just the 8088/80188 use this weird cost-saving thing. This also means that the 8086 can save twice as much data as the 8088 due to the fact that it needs just 1 address to store 16 bits long number while the 8088 needs 2 addresses. And alo you can clearly see that memory can be 16 bits wide. Am I again correct? The last unsolved thing is the HDD, since yes it loads 512 bytes i.e. one sector, but how does it store the data in the memory? Is every byte stored at different address in order to be backwards-compatible with the original IBM PC which used the 8088 so that it can access all of the data or it stores 2 bytes i.e. 16 bits to one address which is more efficient since the 8086 can access the whole 16 bits wide data bus?
Attachments
bits size.png
Post Reply