ASM Conditions in Hooks [Austin]

Well, I've been asked for this, so I thought I would post it here as well. Its a super small tut though, it isn't hard to understand.


So, let's say that we want to check and see if the user is using a ccp or wiimote, and set different addresses for each condition. We could do:


.set joker,0x80200F04

.set ccp,1 #comment this line if you use wiimote/nunchuck

.ifndef ccp

.set joker,0x80200EE0

.endif


#IF YOU KNOW NOTHING ABOUT PROGRAMMING LANGUAGES READ THE SPECIAL NOTE AT THE BOTTOM RIGHT NOW.


For the first line, we set the variable "Joker" to the ccp's addy.


Then we set the variable "ccp" to 1.


We then used an ifndef, which says "If not defined", so, we put ccp after it to check the ccp is defined (in this case the definition would be 1). You can also use the opposite of ifndef, which is ifdef, saying if it is defined.


So, in the statement, we say

Set activator to ccp

Unless variable ccp is not defined

Then set activator to wiimote.


Simple, right?


Now, we can also use bne, and beq, along with cmpw. Cmpw means compare word, bne means for branch if not equal, and beq means for branch if equal. The syntax, in case you don't know it, will be at the bottom of the page. Here is an example, loading a value into a reg and checking that it equals x.


.set sticky,0x200

.set tomahawk,0x201

.set frag,0x202


Grenade1:

Cmpwi r0,sticky

Bne grenade2

Li r0,tomahawk


Grenade2:

Cmpwi r0,tomahawk

Bne grenade3

Li r0,frag


Grenade3:

Cmpwi r0,frag

Bne grenade1

Li r0,sticky


#if you don't understand the grenadex: part of the code, check the bottom syntax list. THIS IS IMPORTANT.


So, we are comparing what is in r0, assuming that is where your grenade type is stored, with the value that variable "sticky" uses. If r0 does not have a sticky grenade in it, it branches to grenade2, however if r0 does hold a sticky grenade, it will load the tomahawks value. I skipped simple C0 steps in both the statements, because if you can't load a value into an address and set the address, this tutorial isn't for you. You can also combine the two, so that its kind of like a LUT. Ex:

#comment any of the below variables if you don't want to use them!

.set sticky,0x200

.set tomahawk,0x201

.set frag,0x202


Grenade1:

.ifdef sticky

Cmpwi r0,sticky

Bne grenade2

Li r0,tomahawk

.endif


Grenade2:

.ifdef tomahawk

Cmpwi r0,tomahawk

Bne grenade3

Li r0,frag

.endif


Grenade3:

.ifdef frag

Cmpwi r0,frag

Bne grenade1

Li r0,frag

.endif


Maybe that wasn't the best example, but I'm sure you understand.


*SPECIAL NOTE:

Hopefully you went through algebra. Setting a variable, is like telling x to hold the value 31 in a math equation. In ppc asm, you use the syntax like this:

.set variablename,value

And you can then later call on that variable in the same routine.


Syntax:

.set (sets variable)

.set variablename,value

Cmpw (compares two things)

Cmpw register,value/variable

Bne/beq (branch if not equal)

Bne/beq functionname *see func explanation at bottom

li (load immediate)

Li register,value


Functions!

Functions are a block of code that only execute when a set condition is met. You can name a function anything, however it would be beneficial to name your function something other then your variables, and you MUST NOT have more then one function with the same name. You use these with the beq/bne instructions, that's why you say


Bne grenade1


Grenade1:


So, the syntax is


Functionname:

You should always have the colon.