I'm trying to write a floating value in ASM but it wont work.
address: 81279524
Breakpoint read:
CR : 28000888 XER : 20000000 CTR : 00000004 DSIS: 00400000
DAR : 81279520 SRR0: 80389960 SRR1: 0000A032 LR : 803898E0
r0 : 00000000 r1 : 807F8490 r2 : 807E43A0 r3 : 81278E80
r4 : 81162B50 r5 : 807F84D8 r6 : 81301E78 r7 : 00000095
r8 : 00000006 r9 : 00000002 r10 : 0000003C r11 : 807F8520
r12 : 803C4C80 r13 : 807DCA20 r14 : 00000000 r15 : 00000000
r16 : 00000000 r17 : 00000000 r18 : 00000000 r19 : 00000000
r20 : 00000000 r21 : 00000000 r22 : 00000000 r23 : 00000000
r24 : 00000000 r25 : 00000000 r26 : 00000000 r27 : 00000000
r28 : 00000000 r29 : 8127C8D0 r30 : 807F8640 r31 : 8127C8D0
f0 : 3F800000 f1 : 00000000 f2 : 3F7FFFF8 f3 : 40400000
f4 : 3F000000 f5 : 3F7FFFFF f6 : BF219454 f7 : BF2FF35E
f8 : BEB80F24 f9 : 3F800000 f10 : 80000000 f11 : 3F800000
f12 : 00000000 f13 : 3F800000 f14 : 00000000 f15 : 00000000
f16 : 00000000 f17 : 00000000 f18 : 00000000 f19 : 00000000
f20 : 00000000 f21 : 00000000 f22 : 00000000 f23 : 00000000
f24 : 00000000 f25 : 00000000 f26 : 00000000 f27 : 00000000
f28 : 00000000 f29 : 00000000 f30 : 00000000 f31 : 00000000
80389960: 880306A0 lbz r0,1696(r3)
80389964: 2C000000 cmpwi r0,0
80389968: 41820010 beq- 0x80389978
8038996C: 801F001C lwz r0,28(r31)
80389970: 54000398 rlwinm r0,r0,0,14,12
80389974: 901F001C stw r0,28(r31)
80389978: 7FE3FB78 mr r3,r31
8038997C: 48065A75 bl 0x803ef3f0
80389980: 3CA0806D lis r5,-32659
80389984: 7C641B78 mr r4,r3
80389988: 38658D18 subi r3,r5,29416
8038998C: 4BCD7D05 bl 0x80061690
80389990: 2C030000 cmpwi r3,0
80389994: 41820010 beq- 0x803899a4
80389998: 801F001C lwz r0,28(r31)
8038999C: 54000398 rlwinm r0,r0,0,14,12
lbz:
li rD,0xLLLL
stw rD,d(rA)
if I jump it say:
803B8590: C02306A4 lfs f1,1700(r3)
lfs:
stwu r1,-16(r1)
stw r11,8(r1)
lis r11,0xHHHH
ori r11,r11,0xLLLL
stw r11,d(rA)
lwz r11,8(r1)
addi r1,r1,16
lfs frD,d(rA)
what's wrong?
Show the assembly around 803B8590.
What value are you trying to write?
803B8574: 7C832378 mr r3,r4
803B8578: 80850584 lwz r4,1412(r5)
803B857C: 38840310 addi r4,r4,784
803B8580: 4BC561C0 b 0x8000e740
803B8584: 00000000 .word 0x00000000
803B8588: 00000000 .word 0x00000000
803B858C: 00000000 .word 0x00000000
803B8590: C02306A4 lfs f1,1700(r3)
803B8594: 4E800020 blr
803B8598: 00000000 .word 0x00000000
803B859C: 00000000 .word 0x00000000
803B85A0: 9421FFF0 stwu r1,-16(r1)
803B85A4: 7C0802A6 mflr r0
803B85A8: 38800000 li r4,0
803B85AC: 90010014 stw r0,20(r1)
803B85B0: 88030705 lbz r0,1797(r3)
I want to write the floating value into 3D000000 with ASM to WiiRd in C2.
803B8590: C02306A4 lfs f1,1700(r3)
803B8594: 4E800020 blr
803B8598: 00000000 .word 0x00000000
803B859C: 00000000 .word 0x00000000
This will make it always read in 3D000000 for the float:
803B8590: lis rX,0x3D00
803B8594: stw rX,1700(r3)
803B8598: lfs f1,1700(r3)
803B859C: blr
change rX to a free register.
I don't understand why you posted the information from 80389960?
code:
C23B8590 00000003
3E003D00 920306A4
C02306A4 4E800020
60000000 00000000
it works, thanks again.
but why:
lis rX,0x3D00
stw rX,1700(r3)
lfs f1,1700(r3)
blr
where is the information about this?
brkirch didn't post it!?
lis rX,0x3D00 // load immediate shifted rX = 3D000000
stw rX,1700(r3) // store word in rX to the address 1700 + r3's value
lfs f1,1700(r3) // this is the original instruction that reads into f1, the value at address 1700 + r3's value
blr
You don't have to use C2 since there is enough room in the game's programming to fit the modification.
So this will work too:
06 (http://geckocodes.org/index.php?arsenal=1&ct=06)3B8590 00000010
3E003D00 920306A4
C02306A4 4E800020
lis rX,0xXXXX
ori rX,rX, 0xXXXX
stw rX,XXXXXX
XXXXXXXXXXX
blr
can I use this on every assembly?
Yep, those are all assembly instructions.
http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixassem/alangref/alangref02.htm
http://class.ee.iastate.edu/cpre211/labs/quickrefPPC.html
http://www.nersc.gov/vendor_docs/ibm/asm/mastertoc.htm
http://pds.twi.tudelft.nl/vakken/in1200/labcourse/instruction-set/
wow thanks alot.
No problem bud. =)
uff another code:
size:
803C0D14: C03E002C lfs f1,44(r30)
803C0D18: C05E0030 lfs f2,48(r30)
803C0D1C: C07E0034 lfs f3,52(r30)
803C0D20: 48207561 bl 0x805c8280
803C0D24: 38610008 addi r3,r1,8
803C0D28: 389E0264 addi r4,r30,612
803C0D2C: 7C651B78 mr r5,r3
803C0D30: 48207041 bl 0x805c7d70
803C0D34: 807E0F00 lwz r3,3840(r30)
803C0D38: 48026E59 bl 0x803e7b90
803C0D3C: 38630024 addi r3,r3,36
803C0D40: 38810008 addi r4,r1,8
803C0D44: 38BD0024 addi r5,r29,36
803C0D48: 48207029 bl 0x805c7d70
803C0D4C: 807E0F00 lwz r3,3840(r30)
803C0D50: 48026E41 bl 0x803e7b90
it freez.
code:
lis r16,0x4000
stw r16,44(r30)
lfs f1,44(r30)
blr
Wow, I'm late to the party...this is what I get for sleeping in. =P
Quote from: James0x57 on July 18, 2010, 12:13:55 PM
I don't understand why you posted the information from 80389960?
Look at the original instruction he broke on [ lbz r0,1696(r3) ], and the instruction he wanted to replace [ lfs f1,1700(r3) ]. My guess is that Deathwolf forgot to check the "Exact" checkbox for the data breakpoint.
Quote from: Deathwolf on July 18, 2010, 12:26:21 PM
but why:
lis rX,0x3D00
stw rX,1700(r3)
lfs f1,1700(r3)
blr
where is the information about this?
brkirch didn't post it!?
brkirch didn't post that method because it is unreliable. rX must be a "safe" register; if it is not you will crash. It's very, very difficult to explain to people how to find a safe register if they are new to ASM. When in doubt, r12 is a safe register 99.9% of the time.
That is why brkirch posted the examples that use stwu r1 etc. He is making room on the stack and saving the previous value of the register he wants to use. This way, when he's done, he can put the old value back. This is
always a safe way to do it.
stwu r1,-16(r1) # make space on the stack (16 bytes)
stw r11,8(r1) # make a backup copy of r11 on the stack
lis r11,0xHHHH # load r11 with the float that we want
ori r11,r11,0xLLLL
stw r11,d(rA) # store the float where we want it to go
lwz r11,8(r1) # restore our backed up copy of r11
addi r1,r1,16 # remove the space we made (16 bytes)
lfs frD,d(rA)
Quote from: Deathwolf on July 18, 2010, 03:58:59 PM
803C0D14: C03E002C lfs f1,44(r30)
803C0D18: C05E0030 lfs f2,48(r30)
803C0D1C: C07E0034 lfs f3,52(r30)
803C0D20: 48207561 bl 0x805c8280
code:
lis r16,0x4000
stw r16,44(r30)
lfs f1,44(r30)
blr
You're on the right track, but I think James' non-C2 patch job has you confused. You do NOT want the blr there! blr = "Branch to Link Register". It is how we "return" from a bl = Branch and Link. bl/blr are like a telephone call. bl is calling someone, blr is hanging up. You put a blr where it shouldn't be, so you hung up the phone in the middle of the conversation.
I think you're also picking registers at random, which is bad. I don't see anything that would suggest r16 is safe there.
What if a pointer was in r16? You would overwrite the pointer with a float. And then later the game would try to use the float you put in r16 as a pointer. And the game would crash. That's why brkirch's example would store r16 on the stack, so we can get the pointer back in r16 when we're done.
If you don't know what registers are safe, use r12.
---
Gecko.NET can log instructions as they are executed. Maybe this log will help you understand how bl/blr work.
803A2E6C: 7FE3FB78 mr r3,r31
803A2E70: 3880001F li r4,31
803A2E74: 48007D5D bl 0x803aabd0 # puts address of next instruction 803A2E78 into LR
| 803AABD0: 80630980 lwz r3,2432(r3)
| 803AABD4: 2C030000 cmpwi r3,0
| 803AABD8: 40820028 bne- 0x803aac00
| 803AABDC: 38600000 li r3,0
| 803AABE0: 4E800020 blr # LR = 803A2E78
803A2E78: 2C030000 cmpwi r3,0
803A2E7C: 4182001C beq- 0x803a2e98
Follow the addresses along. You can see how the bl takes us somewhere else, 803AABD0. We start executing instructions there, until we hit the blr, which takes us back to where the bl left off, 803A2E78.
James' non-C2 patch included the blr because that was part of the original function. A C2 hook should NEVER, EVER have a blr. Every bl must have a matching blr.
---
I just took another look at your code...you're trying to make a size modifier for Super Mario Galaxy 2? I know this because I made a size roller for SMG2, and the addresses are exactly the same. http://wiird.l0nk.org/forum/index.php/topic,5791.msg54813.html#msg54813
My size roller uses non-ASM code types to modify grA. Then at the end, there's a C2 hook that uses the value in grA instead of a value hard-coded into the assembly. Here's the C2 I used.
Hook = 803C0D14: C03E002C lfs f1,44(r30)
grA = 80001830
lis r12,0x8000 # load grA into r12
lwz r12,0x1830(r12)
stw r12,44(r30) # store to x/y/z size addresses
stw r12,48(r30)
stw r12,52(r30)
lfs f1,44(r30) # replaced instruction
yea I see, the addresses are the same.
but how to assembly it?
lis should work on every assembly right?
btw r16 is a free register.
r17/18/19/20 and and and are also nothing (free).
maybe:
lis r18,0x4000
stw r18,44(r30)
lfs f1,44(r30)
btw awesome code dcx2^^
Yes, you can use lis to hard-code a value in for the size modifier. That's how brkirch's original Size Modifier for SMG worked.
(brkirch SMG1 universal size modifier, disassembled!)
lis r29,0xZZZZ # load ZZZZ0000 into r29
stw r29,36(r30) # store to x/y/z size addresses
stw r29,40(r30)
stw r29,44(r30)
lfs f1,36(r30) # replaced instruction
---
I don't know how you are coming to the conclusion that r16-r20 are safe. They aren't. Being 0 does NOT mean safe! I repeat! Being 0 does not mean safe! r12 is almost never 0, but it is almost always safe!
A safe register is one that will be written to before it is read again by the game code (there are also special "volatile registers" that are safe once you cross a bl or blr). r16-r20 are not written to in this area of the game, so they ARE NOT SAFE.
Notice how brkirch used r29 above. If you were to look at the ASM for SMG, you would see that right after brkirch's hook, there's "mr r29,r3". This is over-writing the float that we put in r29 with something else. THAT is what makes a register safe; after the hook, r29 is written to by the game before it is read by the game.
lol what!!??
lis r29,0xZZZZ writes 4000
stw r29,36(r30) <]]]]
stw r29,40(r30) <]]]]] to 3F80
stw r29,44(r30) <]]]]
lfs f1,36(r30) <--- why 36??
Because that is brkirch's size modifier for the FIRST Super Mario Galaxy. He did it hard-coded, instead of a roller like mine.
that last 36 is because that's what it was when the C2 code hijacked it. It could be changed to 40 or 44 and have the same effect.
btw the code doesn't work.
a super freez hmm lol.
assembled code:
C23C0D14 00000003
3FA04000 93BE0024
93BE0028 93BE002C
C03E0024 00000000
Quote from: James0x57 on July 18, 2010, 05:49:00 PM
that last 36 is because that's what it was when the C2 code hijacked it. It could be changed to 40 or 44 and have the same effect.
Actually, the code requires that you hook the first lfs. If you choose e.g. the third lfs, then f1 and f2 will contain un-hacked values by the time your code executes, and you would have to add complementary lfs to your code so f1 and f2 had hacked values.
...well, okay, in this
particular instance, I guess once the game did a second call, the hacked values would be there anyway...but that's only because no one else was writing to that spot afterward.
---
Quote from: Deathwolf on July 18, 2010, 05:55:07 PM
btw the code doesn't work.
a super freez hmm lol
Which code does not work?
1) This code (http://wiird.l0nk.org/forum/index.php/topic,6466.msg54922.html#msg54922) is for SMG
1. It will freeze SMG
2 all the time (EDIT: as you can see (http://wiird.l0nk.org/forum/index.php/topic,6466.msg54925.html#msg54925) because it has the wrong hook address). But it will work great on SMG1, if you can find the address of the hook; brkirch's code is SMG1, and universal, so it's difficult to know the address for a particular region.
2) This code (http://wiird.l0nk.org/forum/index.php/topic,6466.msg54920.html#msg54920) does not use a safe register. r18 is not safe. Use r12 instead of r18.r12 is super-special and safe 99.9%.
All other registers (r0-r11,r13-r31) are
sometimes not safe (
safe is unrelated to value).
Some registers are
NEVER safe (r1,r2,r13).
DCX2 YOUR CODE DOESN'T WORK!
lis r29,4000
stw r29,36(r30)
stw r29,40(r30)
stw r29,44(r30)
lfs f1,36(r30)
it's register 29
assembled:
C23C0D14 00000003
3FA04000 93BE0024
93BE0028 93BE002C
C03E0024 00000000
it freeeeeeezzzzz like "TÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ"
SO:
stw r29,36(r30) these registers are in SUPER MARIO GALAXY """""2"""""
stw r29,40(r30)
stw r29,44(r30)
then you said I should use another register and it doesnt work.
Quote from: Deathwolf on July 18, 2010, 06:21:36 PM
SO:
stw r29,36(r30) these registers are in SUPER MARIO GALAXY """""2"""""
stw r29,40(r30)
stw r29,44(r30)
no. those offsets (36, 40, 44) are SMG 1.
EDIT:
http://wiird.l0nk.org/forum/index.php/topic,6466.msg54920.html#msg54920
Quote from: Deathwolflis r18,0x4000
stw r18,44(r30)
lfs f1,44(r30)
SMG 2. But only one of the offsets. And unsafe register.
http://wiird.l0nk.org/forum/index.php/topic,6466.msg54918.html#msg54918
Quote from: dcx2lis r12,0x8000 # load grA into r12
lwz r12,0x1830(r12)
stw r12,44(r30) # store to x/y/z size addresses
stw r12,48(r30)
stw r12,52(r30)
lfs f1,44(r30) # replaced instruction
also SMG2. Uses safe register. Writes to all three size offsets. r30 is the pointer. The offsets for SMG1 are 36, 40, and 44.
yes but my question.
how to write it for smg2?
none will work
I was hoping you could figure it out on your own. But here goes.
Hook = 803C0D14: C03E002C lfs f1,44(r30)
lis r12,0x4000 # 0x40000000 = 2.0
stw r12,44(r30) # store to x/y/z size addresses
stw r12,48(r30)
stw r12,52(r30)
lfs f1,44(r30) # replaced instruction
C23C0D14 00000003
3D804000 919E002C
919E0030 919E0034
C03E002C 00000000
r12 :-\
I have done this by moonump:
801325C8: C03F00EC lfs f1,236(r31)
lis r12,0x4000
stw r12,236(r31)
lfs f1,236(r31)
C21325C8 00000002
3D804000 919F00EC
C03F00EC 00000000
and it works
the instrucion works on all assembly.
health:
803CE208: 809E06B0 lwz r4,1712(r30)
li r12,0x0006
stw r12,1712(r30)
lwz r4,1712(r30)
C23CE208 00000002
39800006 919E06B0
809E06B0 00000000
and it works again
quick question.
how to change 32 bit?
code:80159DF0: 800303E8 lwz r0,1000(r3)
lis r12,0x05F5
ori r12,r12 0xE0FF
stw r12,1000(r3)
lwz r0,1000(r3)
C2159DF0 00000003
3D8005F5 618CE0FF
918303E8 800303E8
60000000 00000000
it change it to 12345678
It looks like you have the right idea. Use lis/ori.
lis r12,0x1234
ori r12,r12 0x5678
stw r12,1000(r3)
lwz r0,1000(r3)
yep I want to change it to 99999999.
code:
lis r12,0x05F5
ori r12,r12 0xE0FF
stw r12,1000(r3)
lwz r0,1000(r3)
but in the game it's 12345678 lol
decimal 12345678 = hex 0x00BC614E. That's weird. The game might have a maximum.
Try something less than 12345678.
yes 99999950.
but if I try to change it to 00000000, it doesn't overwrite the original value.
hmm what's wrong...
99999950 is not less than 12345678.
please give me a example to activate
try decimal 11111111 = hex 0x00A98AC7
doesn't change anything....
oh my bad.
sry wrong address.
8005F62C: 808DA620 lwz r4,-23008(r13)
lis r12,0x00A9
ori r12,r12,0x8AC7
stw r12,-23008(r13)
lwz r4,-23008(r13)
C205F62C 00000003
3D8000A9 618C8AC7
918DA620 808DA620
60000000 00000000
now it works
80941A34: 889F0001 lbz r4,1(r31)
lis r12,0x2C00
ori r12,r12,0x0000
stw r12,1(r31)
lbz r4,1(r31)
C2941A34 00000003
3D802C00 618C0000
919F0001 889F0001
60000000 00000000
it wont change full 32bit.
it writes: 002C0000 o,o
help pls
80941A34: 889F0001 lbz r4,1(r31)
lis r12,0x2C00 ^
ori r12,r12,0x0000 |
stw r12,1(r31) <-------
lbz r4,1(r31)
w = word = 32 bits
b = byte = 8 bits
---
problem 2 - alignment
A word = 32 bits must be "word aligned". The address must be a multiple of 4. (i.e. 80000000, 80000004, 80000008, 8000000C, 80000010, 80000014, etc).
Look again at your stw. stw r12,1(r31) The offset of 1 is fail, because the address 1(r31) is not a multiple of 4. That's why you must use stb instead of stw.
---
li r12, 0x2C
stb r12,1(r31)
lbz r4,1(r31)
thank you very much for your help dcx2 :)
but it's the same.
it change 002C0000
Yes. stb with 1(r31) is 00xx0000.
stb
0(31) = xx000000
1(31) = 00xx0000
2(31) = 0000xx00
3(31) = 000000xx
stw 0(r31) = xxxxxxxx
sth 0(r31) = xxxx0000
sth 2(r31) = 0000xxxx
hmm okay but what happens if I change the lbz to lwz?
lwz=XXXXXXXX
li r12,0x2C
stw r12,1(r31)
lwz r4,1(r31)
Like he said about alignment,
stw r12,1(r31) -> stw r12,0(r31)
whoops, nvm!
Quote from: Deathwolf on July 19, 2010, 05:34:08 PM
hmm okay but what happens if I change the lbz to lwz?
Fail happens.
Quote
stw r12,1(r31)
lwz r4,1(r31)
alignment fail
r0
and
r1
lis r12,0x2C00
ori r12,r12,0x000
stw r12,0(r31) = 32 bit
lwz r4,1(r31)
code:
C2941A34 00000003
3D80ZZ00 618C0000
919F0000 809F0001
60000000 00000000
lwz r4,1(r31)
alignment fail
---
also, changing lbz -> lwz will probably fail
lis r12,0x2C00
ori r12,r12,0x000
stw r12,0(r31) = 32 bit
lwz r4,1(r31)
this code works.
but this:
lis r12,0x2C00
ori r12,r12,0x000
stw r12,0(r31) = 32 bit
lwz r4,0(r31)
freez
maybe you mean:
lis r12,0x2C00
ori r12,r12,0x000
stw r12,0(r31) = 32 bit
lbz r4,0(r31)
lwz r4,1(r31) will might work, but it still fails alignment. I'm surprised it would work with 1(r31) and freeze with 0(r31). WiiRDGUI will sometimes freeze if you apply C2 codes more than once.
---
What are you trying to do? If the game was using lbz, use stb. If the game was using lwz, use stw. Why change lbz to lwz? Using the wrong alignment will cause problems.
I trought lbz = XX000000
and lwz = XXXXXXXX
like stw and stb
no. lbz will align the xx that it reads.
---
Let's say some memory cell is 002C0000. It is pointed at by r31.
lbz r4,1(r31) ---> r4 = 0000002C
alignment!
---
li r4, 0xC2
stb r4,1(r31) ---> 00C20000
alignment!
---
stb will ignore unaligned bytes
Let's say the memory cell now has 12345678
li r4,0
stb r4,1(r31) ---> 12005678
Quote from: dcx2 on July 19, 2010, 06:47:16 PM
WiiRDGUI will sometimes freeze if you apply C2 codes more than once.
So does Gecko.NET. >.>
dcx2!??!??
lol!?
yes I use WiiRd and it screws sometimes up if I activate the C2 code more times.
Quote from: James0x57 on July 19, 2010, 07:12:48 PM
Quote from: dcx2 on July 19, 2010, 06:47:16 PM
WiiRDGUI will sometimes freeze if you apply C2 codes more than once.
So does Gecko.NET. >.>
Not if you use "Pause While Sending".
it already freez...
Quote from: dcx2 on July 19, 2010, 07:18:05 PM
Quote from: James0x57 on July 19, 2010, 07:12:48 PM
Quote from: dcx2 on July 19, 2010, 06:47:16 PM
WiiRDGUI will sometimes freeze if you apply C2 codes more than once.
So does Gecko.NET. >.>
Not if you use "Pause While Sending".
It still freezes about half the time.
Though I doubt I was only applying one C2 code when it happened.. so maybe that's part of it?
Next time I hack I'll get more details of exactly what I was doing..
Oh and this was on a GCN game so the code handler is a bit outdated, that could also be part of it.
*thread hijack in progress*
It still freezes with Pause While Sending? Applying more than one C2 code shouldn't have any effect.
With WiiRDGUI the process used to include doing a Step after applying the codes and before unpausing, but some testing showed that I didn't need the Step with Gecko.NET. If you can reliably freeze re-applied C2 codes with Gecko.NET, then I can make a special build for you that includes the Step and we'll see if that fixed the problem.