Register Safety for the Beginner
#1
Register Safety for the Beginner



Once your ASM code creating skills have gone beyond 'super basic', you will eventually run into a situation where you will need to use other registers than just the ones that are used by the default/original instruction of your Code. This thread will cover GPR register safety only.

Let's discuss Register Safety

A code creator simply cannot choose at will which registers to use as a temporary space to read and/or write data. Doing so can cause unwanted effects on the game. Even if a code appears to be working, you may be effecting 'hidden' functions of the game.

Let's go over all the General Purpose Registers and explain which ones you are allowed to use...



Register 12 (99.9% Safe)

r12 is the safest register. 99.9% of the time, you can use this register freely. Freely meaning you do not have to restore it's original contents at any point in your source.



Register 11 (99% Safe)

r11 is what I call r12's little brother in regards to safety. 99% of the time, you can use this register freely.



Register 0, and Registers 3 thru 10 (Semi Safe)

r0, and r3 thru r10 are what is known as volatile registers.

You can sometimes use these registers freely w/o restoring their original values, but this is not wise. If you must use these registers, please restore their original value(s) at some point in your code.

Even with that being said, restoring the original value(s) is NOT a 100% guarantee for register safety. Let's say you have a code, and you notice that r7 appears to always be the value of 0 whenever the default instruction at the code's address is executed. Maybe you came to this conclusion because you left a Breakpoint active/on and noticed the pattern of r7 always being Zero. Therefore, at the end of your code, you write the following.. 

li r7, 0 #Restore r7's original value

Good, right? Maybe not. There's still a chance that r7 can be something other than 0. This chance could be uncommon. Which can result in your code becoming "buggy" or your game randomly crashing. Even if r7 always being Zero is true, writing a code in a such a fashion is not "proper".

Generally speaking with the volatile registers, the higher the number, the safer it is. So r10 would be the most 'safest' to use, with r3 being the least safe. r0 plus r3 and r4 are generally less safe than r5 thru r10.

If you must use one of these registers, then stick with r10. I would give r10 a 95% 'safety rating'.



Registers 14 thru 31 (Not Safe)

r14 thru r31 are non-volatile registers. They are called the Global Variable Registers (or just GVR's). Their values must always be preserved.



Registers 1, 2, & 13 (Dangerous)

Never, and I repeat NEVER use r1, r2, and r13!! Even if you backup their values and restore them, this is still dangerous. These registers are used by the CPU to access specific areas of memory related to constants, global variables, etc.  They will be read during interrupts which you will not see or know about. For specific circumstances, r1 can be used with its original value backed up (called pushing/popping the stack), which will be covered in the next segment.

Fyi: r1 is also called sp (stack pointer), and r2 is also called rtoc (register table of contents).




At this point, you are probably wondering what is the correct way to get more free registers. Here's one tip...

Looking Ahead Beyond your Code Address...

We know we can almost always use r11, and r12. Let's say the very next instruction after your code's address is this...

mulli r31, r8, 0x4

You can actually use r31 freely. This is because once your code is completely finished and the next address's instruction is executed by the game, r31 is going to be overwritten regardless. Obviously, this also shows that we cannot utilize r8 at all because r8 is being used as a source register for the mulli instruction.

Now you know that handy trick to get some more free registers, here's a nice method that allows you to use r14 thru r31.

This method is called the 'Push/Pop the Stack' method.

Code:
#Default/original instruction could reside here...

stwu sp, -0x0050 (sp) #make space for 18 registers
stmw r14, 0x8 (sp) #push r14-r31 onto the stack pointer

#Your ASM contents go here

lmw r14, 0x8 (sp) #pop r14-r31 off the stack pointer
addi sp, sp, 0x0050 #release the space

#Default/original instruction could reside here...

As a beginner ASM coder, you don't need to worry about the technical details of how this works.

You can now use r14 thru r31. If you include r11 and r12, you will have 20 free registers to use!

Question: Are there any cons to using the Push/Pop Stack method?

Generally, no. If you are nit picky about shortening the length of assembled code as much as possible, then try to avoid using it.

There is a very very rare chance that this can cause a crash. I would rate it a 99.99% 'success' rate.



Conclusion:

Proper register safety is a must for any code. It is dependent on the responsibility of the coder to do his/her research and have their code(s) be safe for use in the game.

All Credits to:
dcx2
Y.S.
Reply


Messages In This Thread
Register Safety for the Beginner - by Vega - 08-29-2018, 06:13 PM

Forum Jump:


Users browsing this thread: 1 Guest(s)