ASM if - equal,greather,less than

Started by Deathwolf, August 29, 2010, 04:17:10 PM

Previous topic - Next topic

Deathwolf

how to use those following ASM instructions:

ble  target_addr   Branch if less than or equal to (LT or EQ flags of CR0 set)

blt  target_addr   Branch if less than (LT of CR0 set)

beq  target_addr   Branch if equal (EQ of CR0 set)

bge  target_addr   Branch if greater than or equal to (GT or EQ of CR0 set)

bgt  target_addr    Branch if greater than (GT of CR0 set)     

bne  target_addr   Branch if not equal (EQ of CR0 not set)

so my question.
how to use it on codes?

example:

address of live = 81236B32 (16 bit)

lis r12,0x8123 <--- load into address 81236B32
ori r12,r12,0x6B32
lhz   r12,0(r12)
andi. r12,12,0x0002 <--- check if value 0002
blt- THE_END <--- if less than 0002, branch
li r12,0x06 <-- write value 06
stw r12,1712(r30)

THE_END:

lwz   r4,1712(r30)

makes no sense and doesn't work.
NOW WITH button activator:

example:

address of button = 80756102

lis r12,0x8075 <--- load into address 80756102
ori r12,r12,0x6102
lhz   r12,0(r12)
andi. r12,12,0x0200 <--- if value 0200
beq- THE_END <--- if equal with 0200, branch
li r12,0x777 <-- write value 777
stw r12,48(r31)

THE_END:

lwz   r3,48(r31)



the code should be activated if the value is 0001....

lis r12,0x8123 <--- load into address 81236B32
ori r12,r12,0x6B32
lhz   r12,0(r12)
andi. r12,12,0x0001 <--- check if value 0001
beq- THE_END <--- if equal 0001, branch
li r12,0x06 <-- write value 06
stw r12,1712(r30)

THE_END:

lwz   r4,1712(r30)


but it just activate it like:

li r12,0x06
stw r12,1712(r30)
lwz   r4,1712(r30)

wth did I wrong?


thanks for any help!
lolz

Romaap

You have to compare the value first.

There are 2 ways to do this.
1. Compare rA with rB
2. Compare rA with a value

cmpw  rA, rB     Compare Word     rA - rB
cmpwi  rA, value    Compare Word Immediate    rA - value


So in your example you should use

cmpwi r12, 0x0200
beq THE_END

Deathwolf

#2
Quote from: Romaap on August 29, 2010, 07:40:17 PM
You have to compare the value first.

There are 2 ways to do this.
1. Compare rA with rB
2. Compare rA with a value

cmpw  rA, rB     Compare Word     rA - rB
cmpwi  rA, value    Compare Word Immediate    rA - value


So in your example you should use

cmpwi r12, 0x0200
beq THE_END

btw only andi. use 2 registers, cmpwi just one.

this code works:

lis r12,0x8075 <--- load into address 80756102
ori r12,r12,0x6102
lhz   r12,0(r12)
andi. r12,12,0x0200 <--- if value 0200
beq- THE_END <--- if equal with 0200, branch
li r12,0x777 <-- write value 777
stw r12,48(r31)

THE_END:

lwz   r3,48(r31)

dcx2 said: "use bne- with cmpwi"
but bne- = if not equal lol....

I want to do the same by lifes.

lis r12,0x8123 <--- load into address 81236B32
ori r12,r12,0x6B32
lhz   r12,0(r12)
cmpwi r12,0x0002 <--- check if value 0002
beq- THE_END <--- if less than 0002, branch
li r12,0x06 <-- write value 06
stw r12,1712(r30)

THE_END:

lwz   r4,1712(r30)

the result: it freez...
lolz

dcx2

He is using a comparison.  Notice the . after andi..  The . means "set the Condition Register".

andi. is being used to mask off the other buttons, so that the button activator can be used in combination with other button presses.  It's a lot like a 28 code that uses the mask bits.  cmpwi is like a 28 code without mask bits.

I don't see the problem with the code.  Assuming 81236B32 is the button activator, then nothing should happen when left arrow is not pressed, and whenever left arrow is pressed (no matter what else), it should write 6 to 1712(r30).

Note that when you let go, 1712(r30) does not go back to its previous value.  It will still be 6 after you let go of the left arrow.

If it freezes, then your hook might be run between a cmp and it's branch.  Or r12 might be the problem...bully had that issue with another game recently.

btw, cmpwi r12,12,0x0002 is wrong.  It should be cmpwi r12,0x0002

Deathwolf

#4
QuoteAssuming 81236B32 is the button activator, then nothing should happen when left arrow is not pressed

it's the address of health!
it should just run IF the value is 0002. I trought it works with andi. and cmpwi too...

lis r12,0x8123  <-- load into Health address
ori r12,r12,0x6B32
lhz   r12,0(r12)
cmpwi r12,0x0002 <---- check if 0002
beq- THE_END <--- if equal (beq) branch
li r12,0x06
stw r12,1712(r30)

THE_END:

lwz   r4,1712(r30)

same like this:
29236B32 00000002
C23CE208 00000002
39800006 919E06B0
809E06B0 00000000


btw thanks for your answers!
lolz

dcx2

Branch skips over stuff.  So you would be skipping over li/stw when r12 == 2.  I think you want bne instead.

andi. only works with masking.  28 codes that have FFDF type stuff.  Otherwise, use cmpwi.

Deathwolf

yes if equal with 0002, activate li/stw.

bne = if not equal hmm
but why bne? activate if EUQAL with 0002 (beq)

lis r12,0x8123
ori r12,r12,0x6B32
lhz   r12,0(r12)
cmpwi r12,0x0002
bne- THE_END
li r12,0x06
stw r12,1712(r30)

THE_END:

lwz   r4,1712(r30)

idk but it freez.
lolz

dcx2

bne skips the li/stw if r12 is not equal to 2

Deathwolf

#8
so this is it?

lis r12,0x8123
ori r12,r12,0x6B32
lhz   r12,0(r12)
cmpwi r12,0x0002
bne- THE_END
li r12,0x06
stw r12,1712(r30)

THE_END:

lwz   r4,1712(r30)

wow now it works perfectly!
thanks alot!!
lolz

Deathwolf

does this work too?
if less than skip li/stw

lis r12,0x8123
ori r12,r12,0x6B32
lhz   r12,0(r12)
cmpwi r12,0x0002
blt- THE_END
li r12,0x06
stw r12,1712(r30)

THE_END:

lwz   r4,1712(r30)
lolz