Announcement

Collapse
No announcement yet.

[PPC ASM] confused with syntax of conditional branches. Help needed

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • [PPC ASM] confused with syntax of conditional branches. Help needed

    Hi,
    I've been trying to write an assembly code that corrupts any animated thing in a game during the first 85 seconds (2550 frames (0xA00). After that everything should be normal.
    To do that I'm using the value that increases by 0x1 every frame after a level or cutscene is loaded.

    First I'd like to load the address of the increasing value into r8. no problem so far.
    then I want to load the value of this address into r10.
    No problem, too.
    Now I need to load the address where I want to write my custom value at into r8. Easy.
    Now I want to immediately compare the value of r10 with 0xA00. I think I've done that all right.

    Now I want to branch 0x18 ahead if r10 is lower than 0xA00. if not, the branch is skipped and the defauult value will be written to the address that is now in r8. The Problem is, that each time I want to assemble the blt instruction the disassembler starts nagging telling me the offset is out of range. But definitely isn't.

    Any advice?

    Click image for larger version

Name:	blt help needed.jpg
Views:	1
Size:	171.8 KB
ID:	163825

    blt- 0x18, blt- 0x800035A4, blt 0x18, blt 0x800035A4 don't work
    i even copied the syntax of an existing code being viewed through ASM <-> wiird converter



    oh, well, here it is as text with all proper hex values to prevent any more confuseions:


    lwz r31,12(r1) // original instruction. Coming from 800053C8
    lis r8, 0x803D /* load address of the growing
    ori r8, r8, 0x1F48 integer into r8 */
    lwz r10, 0 (r8) // load growing Int from address in r8 (803D1F48) into r10
    lis r8, 0x804C /* load animation
    ori r8, r8, 0xB4EC corrutpor address */

    cmpwi cr?,0, r10, 0xA00 // Compare r10 with 0xA00 ??????????????????
    blt- 0x800035A4 // goto 800035A4 if r10 is lower than 0xA00 ?????????????

    lis r9, 0x3B40 // load 0x3B40 into r9
    stw r9, 0 (r8) /* store 0x3B400000
    stw r9, 4 (r8) into address of r8 (804CB4EC)
    stw r9, 8 (r8) */ + offsets
    b 0x800035B4 // goto 800035B4

    lis r9, 0x4040 // load 0x4040 into r9
    stw r9, 0 (r8) /* store 0x40400000
    stw r9, 4 (r8) into address of r8 (804CB4EC)
    stw r9, 8 (r8) */ + offsets

    lis r8, 0x0000 /* set all used
    ori r8, r8, 0x0000 registers to
    lis r9, 0x0000 their defaults
    lis r10, 0x0000 to prevent
    ori r10, r10, 0x0000 */ possible crashes
    b 0x800053CC // goto 800053CC


    Edit:
    And is the comparing instruction right?
    Nothing has changed.. i think the comparison fails
    Last edited by CosmoCortney; 06-12-2015, 10:44:18 PM.
    My Website
    Hacking YouTube Channel


    No requests, please

  • #2
    Not sure if this assembler/disassembler whatever works this way, but as a general rule, you need a + or - when branching some number of operations. A lot of assemblers will interpret an unsigned value as an absolute address.

    I tried a partial version of your routine, and blt- 0x18 is compiled to a code just fine. Although, I believe you need to be using blt+ (which also compiles fine). I couldn't get an absolute address to compile. The assembler might be too simple, or you need to specify a third switch that isn't obvious. There's no documentation with this damn thing, so it...well, I just tried blt= and it actually compiled with an absolute address, but I think it output a garbage code. I'm not familiar enough with PowerPC that I can tell what it did differently just by looking at it.

    Edit: OK, they didn't add funky, modified mnemonics for branching backwards and forwards in memory, the parser just doesn't care much where that +/-/= switch is. It works right next to the op code, next to the operand, or with any amount of whitespace. No idea why they elected to tack the sign onto the op code when going from cheat to assembly.

    Edit 2: Ugh, Jesus. The + and - are actually switching the "likely" branch hint, and it doesn't interpret offsets much at all. The minus is appropriate by convention, since the branch is traveling ahead, but if I want to compile a branch that goes backwards 0x18 with this thing, I have to key in blt- +0x18, which is bonkers to me. Do yourself a favor and use labels in your assembly code.
    Last edited by Pyriel; 06-13-2015, 10:09:07 PM.

    Comment


    • #3
      Thank you for your effort!
      blt- 0x800035A4 works fine.
      I think I have figured out the other problem.. I removed the "Cr" from the syntax and it worked fine. I thought I had to specify a Cr where the result of the comparison is stored (<, >, = or !=).

      Is it automatically stored in a volatile Cr?
      My Website
      Hacking YouTube Channel


      No requests, please

      Comment


      • #4
        According to the documentation cr0 is the default. Other fields are available to make it easier to combine conditions or do multiple at the same time. I assumed "cr?,0" in your code was just a typo for cr0, which is a little redundant, but should have been fine.

        Comment


        • #5
          the "cr?" ment that i wasn't sure what cr to use. the 0 behind it has to be used for 32bit based processors. but that was always removed by the debugger) so, lucky cr0 seems to be volatile in my case.

          May I ask you if you know how to use another cr?
          the documentation tells me that cr0 and 5 - 7 are volatile. But I won't trust this always since I have sometimes experienced that volatile claimed registers didn't act like this, too.
          (The value in the register changed many times, so I thought It'd be fugitive. But overwriting it with a custom value froze the process. I couldn't restore it to the previous value because as said before it changes all the time and is used)
          My Website
          Hacking YouTube Channel


          No requests, please

          Comment


          • #6
            Well, the 0 is removed because cmpwi is a shorthand mnemonic that specifies the width for itself. If you use the more generic cmpi, then it's required so the assembler can determine whether to sign extend and how much data is being compared.

            I'm not sure what you mean by "use another cr". You'd just specify it in the relevant op code, but it sounds like you're asking how to work around other things changing the value, which is a larger topic. In this context "volatile" means it can be destroyed by function calls and should not be relied upon to maintain it's value across them. You want something that's preserved or nonvolatile by convention if you need to set something in a cr and then check it after 3 functions have been called. If you need to use a volatile register, you have to preserve and restore it yourself in the calling function.

            Comment


            • #7
              This might help:
              https://www.sendspace.com/file/k0w0rw
              July 7, 2019

              https://www.4shared.com/s/fLf6qQ66Zee
              https://www.sendspace.com/file/jvsdbd

              Comment

              Working...
              X