WiiRd forum

Wii & Gamecube Hacking => Wii Game hacking help => Topic started by: live2play on September 23, 2010, 09:05:38 AM

Title: lwz syntax
Post by: live2play on September 23, 2010, 09:05:38 AM
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)
Title: Re: lwz syntax
Post by: Romaap on September 23, 2010, 09:18:16 AM
set a breakpoint on that line and when it breaks check what value is in r0, it should be between 0x80000000 and 0x81000000
Title: Re: lwz syntax
Post by: dcx2 on September 23, 2010, 02:39:20 PM
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.
Title: Re: lwz syntax
Post by: Romaap on September 23, 2010, 10:43:15 PM
Ah, yes.
I totally forgot that.
Title: Re: lwz syntax
Post by: live2play on September 24, 2010, 12:49:07 AM
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?
Title: Re: lwz syntax
Post by: dcx2 on September 24, 2010, 01:02:03 AM
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.
Title: Re: lwz syntax
Post by: live2play on September 24, 2010, 05:22:41 PM
Thanks for the thorough explanation, as always....and the compliment.  I try.  :)