ASM explanations...

Started by Stuff, August 24, 2011, 02:19:59 AM

Previous topic - Next topic

Stuff

Hope it's alright to post this here. I want to use this thread much like I did with codetype explanation.

So I'm a noob when it comes to this. I wasn't gonna post questions because I can figure this out myself. Or so I thought. >.> So I'm just gonna ask what an instruction does when the explanation in here or here aren't too obvious or I just can't find what I'm looking for there. Hope someone doesn't mind answering my questions.

Anyway, I'll start with branches. I thought I had them all figured out but then...I started using 'step into' on gecko.net and this happened about 3x in a row.

r0 != 36

8041553C:  2C000024   cmpwi   r0,36
80415540:  40820024   bne-   0x80415564

not the same cmpwi or branch, but each time I expected this to be "true" and gecko.net said "Not Taken" and the next step into didn't branch. >.>
This was in a loop that I stopped following because that happened. The next cycle it was "Taken" because r0 != 36 still. But why didn't it "take" it before? I think it might have something to do with the +/-. I read somewhere that the +/- is to eliminate it's prediction or something, but I never thought it was a big deal. But maybe it is a big deal. Maybe that's why it wasn't taking the argument when I expected it to be true. Maybe...idk.

----
[spoiler=an image to illustrate what I'm talking about][/spoiler]
.make Stuff happen.
Dropbox. If you don't have one, get it NOW! +250MB free if you follow my link :p.

Mod code Generator ~50% complete but very usable:
http://dl.dropbox.com/u/24514984/modcodes/modcodes.htm

dcx2

Remember that the registers are in hex, but the disassembly is in decimal.

As far as your image, it looks correct.  r0 = 0x2E = 46.  cmpwi r0,46 = equal bit of CR will be set.  Since equal bit is set, bne- will not be taken.

A cmp is actually a sub that doesn't store the result anywhere.  The CR is split into eight 4-bit fields.  These are cr0 thru cr7.  cr0 is usually assumed (all instructions ending with . will affect cr0 as if there was a cmpwi rX,0).  cmp and branch instructions can specify other cr fields; Gecko.NET doesn't support them and it will guess wrong.

The + and - are "static branch hints".  + means "probably taken", and - means "probably not taken".  In general, the compiler assumes all branches going backwards will be taken (i.e. it's a loop!).

Stuff

#2
alright. So now I'm afraid of breaking something. This is the original instruction here.
817C5270:  4CC63182   crclr   6,6

I want to replace this line with stw   r9,1952(r18) because this would do the max heal monster. And then quickly restore the original instruction. BUT... it braches and a few instructions later:
8005C82C:  40860024   bne-   cr1,0x8005c850

I could just test the code out, but I just feel like this would cause some funky effects at some point even if I did test it..

I can of course do a C2 and just include both instructions in it, but then I have to end it with a nop so it can branch back. And that would end up being a 5 line code. I mean, it's still shorter than my code, but I was aiming at 4 lines.

----
nvm. The code didn't even work. weird that it doesn't though. It's the same idea I used for map attached to hud. The C3 by itself works, but I can't do a 04 after the if.
.make Stuff happen.
Dropbox. If you don't have one, get it NOW! +250MB free if you follow my link :p.

Mod code Generator ~50% complete but very usable:
http://dl.dropbox.com/u/24514984/modcodes/modcodes.htm

dcx2

lol, you shouldn't really sweat one line so much.  Get a code working first, then optimize.  There were many versions of my RT4EAF encounter roller and believe it or not, it's very tightly optimized, to the point where it's difficult to read the source.

crclr will clear a condition register field.  That looks like it clears cr6.  In terms of cr1, you'd want to look for something in the current function that was doing cmpwi cr1.  You can use the disasm search up for cr1 and you should find it.  Although I'm not sure why you're trying to hook that instruction instead of something else.

Stuff

Oh. cuz the instruction directly before it was 817C526C:  813207A4   lwz   r9,1956(r18). Kind of need that r9.

Regex search?
.make Stuff happen.
Dropbox. If you don't have one, get it NOW! +250MB free if you follow my link :p.

Mod code Generator ~50% complete but very usable:
http://dl.dropbox.com/u/24514984/modcodes/modcodes.htm

dcx2

It's simple search by default, to use regex you must check about tab.

It usually helps to Copy Function into a spoiler any time you're trying to make a hook.  It sounds like that's the hook you actually want.

Stuff

Well I wanted to keep this thread for general asm questions like "wut is mflr". Just an example. I know what it is. I'll ask if it ever doesn't make sense.

Oh no... Now that I was gonna post the Copy Function, I got a different Read BP. And I just realized why. The old one was the MID XD. Not a good hook at all.

[spoiler]
CR:28200488  XER:00000000  CTR:801542D0 DSIS:00400000
DAR:9014C0E0 SRR0:8012ED08 SRR1:0000B032   LR:8012ED08
  r0:8012ED08   r1:807AD530   r2:8079DAA0   r3:00000002
  r4:80A2C398   r5:00000000   r6:00000000   r7:00000000
  r8:9014C282   r9:00000096  r10:80000000  r11:807AD560
r12:801542D0  r13:80798E20  r14:805A0000  r15:00000000
r16:00000001  r17:000000FF  r18:9014B940  r19:00000000
r20:00000000  r21:00000000  r22:0000000D  r23:00000000
r24:00000000  r25:00000000  r26:00000000  r27:801510C4
r28:0000C320  r29:00000000  r30:9014B940  r31:9014B940

8012ECF0:  9421FFE0   stwu   r1,-32(r1)
8012ECF4:  7C0802A6   mflr   r0
8012ECF8:  90010024   stw   r0,36(r1)
8012ECFC:  93E1001C   stw   r31,28(r1)
8012ED00:  7C7F1B78   mr   r31,r3
8012ED04:  4BFFFF71   bl   0x8012ec74
8012ED08:  801F07A0   lwz   r0,1952(r31) ##break
8012ED0C:  C86291C8   lfd   f3,-28216(r2)
8012ED10:  6C008000   xoris   r0,r0,32768
8012ED14:  9001000C   stw   r0,12(r1)
8012ED18:  3C604330   lis   r3,17200
8012ED1C:  90610008   stw   r3,8(r1)
8012ED20:  C8010008   lfd   f0,8(r1)
8012ED24:  EC401828   fsubs   f2,f0,f3
8012ED28:  801F07A4   lwz   r0,1956(r31) ##max hp is being load to r0. I want to stw after this. But something is gonna break >.>
8012ED2C:  6C008000   xoris   r0,r0,32768
8012ED30:  90010014   stw   r0,20(r1)
8012ED34:  90610010   stw   r3,16(r1)
8012ED38:  C8010010   lfd   f0,16(r1)
8012ED3C:  EC001828   fsubs   f0,f0,f3
8012ED40:  EC020024   fdivs   f0,f2,f0
8012ED44:  FC000840   fcmpo   cr0,f0,f1
8012ED48:  4C401382   cror   2,0,2
8012ED4C:  7C600026   mfcr   r3
8012ED50:  54631FFE   rlwinm   r3,r3,3,31,31
8012ED54:  83E1001C   lwz   r31,28(r1)
8012ED58:  80010024   lwz   r0,36(r1)
8012ED5C:  7C0803A6   mtlr   r0
8012ED60:  38210020   addi   r1,r1,32
8012ED64:  4E800020   blr   
[/spoiler]
But it's not good. I thought it might read the hp often, but it doesn't. I waited a little while to get this BP again. w/e. I think the max heal code is fine the way it is. Guess it's time to go back to "monsters don't see me".
.make Stuff happen.
Dropbox. If you don't have one, get it NOW! +250MB free if you follow my link :p.

Mod code Generator ~50% complete but very usable:
http://dl.dropbox.com/u/24514984/modcodes/modcodes.htm

Bully@Wiiplaza

C212ED28 00000002
3C00XXXX 6000XXXX
901F07A4 00000000

Set your amount by inserting the value into XXXX.
It stores it afterwards.
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

dcx2

That function is doing some conversions to float.  Pay attention to this template.

8012ED08:  801F07A0   lwz   r0,1952(r31) ##break
8012ED0C:  C86291C8   lfd   f3,-28216(r2)
8012ED10:  6C008000   xoris   r0,r0,32768
8012ED14:  9001000C   stw   r0,12(r1)
8012ED18:  3C604330   lis   r3,17200
8012ED1C:  90610008   stw   r3,8(r1)
8012ED20:  C8010008   lfd   f0,8(r1)
8012ED24:  EC401828   fsubs   f2,f0,f3

Read this post for a breakdown of what is happening here.  http://wiird.l0nk.org/forum/index.php/topic,6593.msg56266.html#msg56266

Ultimately, when this is done, the value in r0 (current health, I believe) will be cast to a 32-bit single precision float.  The process is then repeated for the max health.  f0 = max health float, f2 = current health float.

8012ED40:  EC020024   fdivs   f0,f2,f0
8012ED44:  FC000840   fcmpo   cr0,f0,f1
8012ED48:  4C401382   cror   2,0,2
8012ED4C:  7C600026   mfcr   r3
8012ED50:  54631FFE   rlwinm   r3,r3,3,31,31

This is then doing f0 = current / max.  Then it's comparing the resulting quotient against f1, which is an argument passed in from the caller, and places the result of the compare in cr0.  It then ors cr2 and cr0 together; dunno why, because cr2 isn't used at all.  It then puts the cr result into r3 and masks off what I think is the equal bit of cr0 (I may be wrong, you should verify).  This is then returned to the caller via r3; 1 = equal, 0 = not equal.

---

hook   8012ED08:  801F07A0   lwz   r0,1952(r31)

lwz r0,1956(r31)   # read max health
stw r0,1952(r31)   # write to current health
# no need for original instruction; r0 has the right value in it already

C212ED08 00000002
801F07A4 901F07A0
60000000 00000000

---

EDIT: btw were you actually asking what mflr is doing?

Stuff

Quote from: dcx2 on August 26, 2011, 02:42:22 PM
hook   8012ED08:  801F07A0   lwz   r0,1952(r31)

lwz r0,1956(r31)   # read max health
stw r0,1952(r31)   # write to current health
# no need for original instruction; r0 has the right value in it already

C212ED08 00000002
801F07A4 901F07A0
60000000 00000000

---

EDIT: btw were you actually asking what mflr is doing?
>.> wut? r0:8012ED08. That's not someone's hp.
---
no that was just an example of what I meant to use this thread for.

And the code Bully Posted would only write XXXX to the hp. But that gave me an idea. Since it's only read sometimes, I could do "Monsters have Regen". I was thinking something like this:

li rX, 10 ##or 20 or something
divw rY, r0, rX ##why isn't there a divwi
add r0, r0, rY  ##current+quotient
stw r0, 1952(r31) ##healed 5-10 or something%
## do what needs to happen to not break the instructions. (happened with the box. was funny seeing so many exceptions caught. lol)

I just need to make sure this doesn't run every time the monster is hit. That would suck.

The float thing, I'll have to look into. That's extra new to me.
.make Stuff happen.
Dropbox. If you don't have one, get it NOW! +250MB free if you follow my link :p.

Mod code Generator ~50% complete but very usable:
http://dl.dropbox.com/u/24514984/modcodes/modcodes.htm

dcx2

#10
Quote from: Stuff on August 26, 2011, 03:55:40 PM
>.> wut? r0:8012ED08. That's not someone's hp.
Breakpoints occur before the instruction is executed.  You're seeing the old, stale value of r0.  You can right-click Show Mem to get a peek at the value that will be lwz'd.  (EDIT: you can also type in a new value and press Enter to do a 32-bit poke)  Or you could press Show Mem and go check it out in the memview tab.

Press Step Into and the instruction will execute, loading the monster's hp into r0.

Stuff

Oh. I was looking at it wrong. I was think that if you never lwz   r0,1952(r31), how could r0 have the correct value.  But I see it now. If your storing r0 to 1952(r31), why lwz it. :p Alright cool. Now that won't break anything. It still doesn't change the fact that it reads only sometimes. But I'll check to find when it reads later when I come back. That hook looks good for monsters have regen. lol.

Is it possible to divide or multiply by not an integer? Like r0*0.85. I don't think it is. And now I see there's no mulw. >.<
.make Stuff happen.
Dropbox. If you don't have one, get it NOW! +250MB free if you follow my link :p.

Mod code Generator ~50% complete but very usable:
http://dl.dropbox.com/u/24514984/modcodes/modcodes.htm

dcx2

Quote from: Stuff on August 26, 2011, 05:22:24 PM
Is it possible to divide or multiply by not an integer? Like r0*0.85. I don't think it is. And now I see there's no mulw. >.<
It is possible to multiply by fixed-point integers, although the process isn't exactly straightforward.  Google fixed point for more info.

For instance, if you wanted to multiply r0 = 0x48 by 0.25, you would do something like this.  (I think - this is untested and it's been a while since I used fixed point integers, and fractional binary is not very straightforward)

lis r12, 0x4000   # All 32-bits are "behind" the decimal point, so r12 = 0b0.0100 0000 00... = 0.25
mulhw r0,r12,r0  # r0 = the upper 32-bits of r12 * r0

The product of two 32-bit numbers will be 64-bits.  If you consider r12 to be "behind the decimal point" then the upper 32-bits will be the product of the fixed point multiplication of r0 and r12.  The lower 32-bits would be the fractional remainder.

Stuff

>.> Yeah. I'll just uh...stick with this. r5 looks like it's free:

lwz r0, 1956(r31)   ## read max health
li r5, 20
divw r5, r0, r5 ##divide max health by 20. 5%
lwz r0, 1952(r31) ##read current health
add r0, r0, r5 ##healed by 5%
stw r0, 1952(r31) ##store new hp
:/ nop 00000000

Gonna see if this actually works now.
.make Stuff happen.
Dropbox. If you don't have one, get it NOW! +250MB free if you follow my link :p.

Mod code Generator ~50% complete but very usable:
http://dl.dropbox.com/u/24514984/modcodes/modcodes.htm

dcx2

Quote from: Stuff on August 27, 2011, 12:49:08 AM
r5 looks like it's free:
What makes you believe that it's free?  I mean, it is free/safe.  But I have a feeling that you believe it is safe for the wrong reasons.

---

Also, if you don't mind dividing by powers of 2, this can be simplified.

lwz r12, 1956(r31)   # read max health
srawi r12,r12,4       # r12 = r12 / 16
lwz r0, 1952(r31)    # read current health
add r0, r0, r12       # healed by 5%
stw r0, 1952(r31) ##store new hp