2

In Knuth's Fascicle 1 on MMIX, the "Memory and Registers" section on page 4 states:

"thus if x is any octabyte, M[x] is a byte of memory."

and

"thus if x is any byte, $x is an octabyte."

How can x be an octabyte (64 bits) and M[x] be a byte (8 bits)? Conversely, how can x be a byte and $x be an octabyte?

gnat
  • 20,543
  • 29
  • 115
  • 306

3 Answers3

4

MMIX is a notional 64-bit computer, so its address bus has 64 lines and it can be fitted with up to 2^64 memory cells. Each of these cells, however, holds 1 byte (8 bits) and not 64 bits, therefore you have 2^64 bytes (not octobytes) of RAM. (It is customary to measure RAM in bytes and not in double-, quad- or octo-bytes even when the architecture has more than 8 bits. It is also convenient to retrieve individual bytes from memory because many algorithms require only small numbers in many places. In practice, processor caches obscure this distinction anyway.)

The registers, however, are full 64-bit registers, therefore $x is an octobyte, not just a byte. Again, this is a convention for processor architecture rather than a fixed law, but most architectures that claim to be X-bit (for an impressively large value of X) also sport X-bit registers, so that when you do want to load X bits from memory simultaneously, you can receive them in just one register without spilling.

Kilian Foth
  • 110,899
2

Because “plain ol’” memory addresses address bytes. Notice, though, that if you are addressing more than one byte of memory multiple memory addresses point to the same thing.

To be sure, there are 2^(64) bytes of memory, 2^(63) wydes, 2^(62) tetrabytes, and 2^(61) octabytes. You basically end up with 3 ignored bits when addressing octabytes.

In other words, if f(x) is a function from an address x to its memory cell (think of *x in C), f(x) isn’t bijective; moreover, f(x) is only a binary operation when you’re addressing octabytes (i.e., for x in X f(f(x) is in X too).

You can think of it like pointers to int, double, etc.

Nice to see people reading about MMIX!

0

There are two separate notations defined here.

This defines the "M[x]" notation where x is an address - addresses are 8 bytes (octabytes):

"The cells of memory are called M[0], M[1], ..., M[264 - 1]; thus if x is any octabyte, M[x] is a byte of memory"

M[x] is shorthand for M1[x] - it refers to the single byte at address x. Similarly M2[x] refers to 2 bytes associated with address x. And M4[x] is 4 bytes, M8[x] is 8 bytes of memory.

It gets interesting with M2[x], M4[x], M8[x] because "Mt[x]" is an aligned reference to memory. So M4[x] is not 4 bytes starting at address x. Rather it is the 4 bytes at 4-byte-aligned x.

Suppose addresses 1000-1007 contain hex: 01 23 45 67 89 ab cd ef. Then M4[1002] is not 45 67 89 ab. Instead it is 01 23 45 67 because 1002 aligned to 4 bytes is address 1000. So M4[1000] = M4[1001] = M4[1002] = M4[1003].

The second notation is "$x" where x is a register number. MMIX has 256 registers numbered 0-255. Each register is 64-bits wide. So any register number fits in one byte. And $x - the content of register x - is one octabyte.

"The general-purpose registers are called $0, $1, ..., $255; thus if x is any byte, $x is an octabyte"

You just need to realize "x" in the two notations mean different things - the confusion may come from them being defined next to each other.