First of all, to short circuit your question, I must say that you can not ready from multiple memory locations at the same time in the MIPS architecture.
Second, your interpretation of the offset is wrong. You assumed the offset is a bit offset, while it's actually an offset in bytes. Meaning if you give the address 2 and offset 4, the memory location to be read from will be 6 (2+4).
Third, more details into the MIPS lw (load word) instruction. The syntax is as follow:
lw \$d, off(\$r), where \$d is the destination register (where the word is loaded to), off is an immediate 32 bit constant and \$r is your base register. What happens is as follow:
- The target ram address is calculated by adding off and the value in \$r.
- The calculated address in loaded in the memory register
- The control unit enabled the RAM to get the value at the address
- The value is set to the \$d register
Fourth, something I haven't mentioned before, related to the addressing pattern of the ram. As you may know, the ram stores bytes, no actual words. What's the problem you may wonder? It's something called word alignment, and it's the reason why you couldn't load a word from address 6. A word is a 4 byte value, and for fast design purposes, when loading a word, the address has to be a multiple of 4. I won't go in the design details, but suffice to say that this permits greater memory transfer speed than allowing any address.
What this means is that when loading and storing words, you have to respect the word boundaries. If you try to read from a bad memory location i.e. not a multiple of 4, e.g. 6, you will have a memory exception; meaning you program likely crashes.
In practice, this mean that if you have to store tree words a,b and c, you could store them at address 0x01234560, 0x01234564 and 0x01234568.
EXTRA: why use an offset
So, in my last example, you might have noticed my words were close in memory, but i didn't start at 0x00000000. Actually, the first word starts at adress 0x01234560. Here's how you can take that into consideration with the lw syntax.
- First, set the value of \$r to 0x01234560
- Then, to load a, you write lw \$d, 0(\$r). The will load the value at 0+\$r, 0 + 0x01234560 = 0x01234560
- Then, to load b, you write lw \$d, 4(\$r). The will load the value at 4+\$r, 4 + 0x01234560 = 0x01234564
- Then, to load c, you write lw \$d, 8(\$r). The will load the value at 8+\$r, 8 + 0x01234560 = 0x01234568
I hope this completely answers your question. The only thing I haven't touched is why you'd end up at such complex memory locations. Short answer: it's due to the structure of the compiled program and the way it's loaded into memory. I suggest you look further into that before delving deeper into the world of computer electronics. A sound knowledge of the structure of a program will greatly help understand why the CPU and instruction set were made that way.