Maybe I'm missing something simple here, but I need to be able to read the data that is 12 words (48 decimal/0x30) less than the MEM1 value in a register (r0) and store the data that address into another register (r8). When I use the following syntax, the game just stays on this line of code and won't proceed. It's as if the syntax is incorrect.
lwz r8,-48(r0)
set a breakpoint on that line and when it breaks check what value is in r0, it should be between 0x80000000 and 0x81000000
lwz is one of those (rA|0) instructions.
http://pds.twi.tudelft.nl/vakken/in1200/labcourse/instruction-set/lwz.html
These instructions will treat the register r0 as the value 0 when it is used in place of the rA operand, instead of using the contents of r0. So lwz r8,-48(r0) is actually reading the address 0xFFFFFFB8. ( = 0 - 48)
This feature is actually a sort of third "anchor" register (like r13 and r2). It's meant to allow easy access to the first 32k or so of memory, but unfortunately we never ever use any of that in our hacks.
You're going to need to move the value from r0 into some other register in order to use it as the rA operand for lwz.
Ah, yes.
I totally forgot that.
Thanks! I'll always move r0 to another register rather than using to to perform a read. Is this also true for write operations like stw that involve r0?
Yes, but be careful with your wording. This concept is a little...warped.
Specifically, if the datasheet says "(rA|0)", then the PPC will ignore the value in r0 and use the value 0 instead when r0 is specified as the rA operand for the instruction.
There are two points to stress. The first is that the datasheet must say (rA|0) in it. If it just says rA, then the value in r0 will actually be used. Compare addi to add.
http://pds.twi.tudelft.nl/vakken/in1200/labcourse/instruction-set/addi.html
http://pds.twi.tudelft.nl/vakken/in1200/labcourse/instruction-set/add.html
The second point is that this detail only applies to the rA operand. rS, rB, rD, etc are unaffected (assuming there's no (rB|0) or something...).
So it is quite okay to lwz r0,-48(r3) (rD = r0). But lwz r3,-48(r0) will fail. In symmetrical fashion, stw r0, -48(r3) will work, but stw r3, -48(r0) will fail, because stw is one of those (rA|0) instructions.
http://pds.twi.tudelft.nl/vakken/in1200/labcourse/instruction-set/stw.html
---
I imagine this sounds pretty weird. What use is this feature? It just makes life difficult, right?
Well...consider the Load Immediate instruction, li. How, exactly, does li load the immediate into the destination? A careful examination of the machine code for an li will reveal that li is actually addi!
li r3,12
addi r3,r0,12
Those instructions have identical machine code, because the r0 is treated as 0. Thus, the li instruction is called a mnemonic; it's not a "real" instruction, but the assembler lets us pretend it is so we don't have to write "addi r3,r0,12" all the time.
EDIT:
also, I'd like to thank you, live2play, because you always ask interesting questions and you seem to grok the answer pretty well. It's always a pleasure to answer your questions.
Thanks for the thorough explanation, as always....and the compliment. I try. :)