Tutorial on the 'BL-Trick' + Psuedo Ops - Printable Version +- Mario Kart Wii Gecko Codes, Cheats, & Hacks (https://mariokartwii.com) +-- Forum: Guides/Tutorials/How-To's (https://mariokartwii.com/forumdisplay.php?fid=45) +--- Forum: PowerPC Assembly (https://mariokartwii.com/forumdisplay.php?fid=50) +--- Thread: Tutorial on the 'BL-Trick' + Psuedo Ops (/showthread.php?tid=977) |
Tutorial on the 'BL-Trick' + Psuedo Ops - Vega - 12-05-2018 Tutorial on the 'BL-Trick' + Psuedo Ops
Requirements: Be at least a Beginner Level coder that already knows the basics and has made a few simple codes Understand basic Loops - https://mariokartwii.com/showthread.php?tid=975 Chapter 1: Introduction Beginner and Intermediate Coders may run into a situation where they need to overwrite a string of data in dynamic memory. The Coder may have found a Hook address that, when executed, points to the start of an important String of Data that can be edited. Once the Data has been edited, the effects are seen on the user's game. The beginner or intermediate coder might try a method like this.... Code: lis rX, 0xXXXX He/she would probably use a repetitive series of lis+ori instructions to write out the string of data and then use a basic Loop to transfer the data from the registers to dynamic memory. Another method would still include the usage of lis+ori, but instead of a loop for the transfer, a stmw instruction is used (multiple word write). The downside is that this method requires the address of the start of the Data to be divisible by 4 and it requires the 'Push/Pop' the stack method. There is even a couple of more similar methods (stswi and stswx), but at the end of the day, there's a superior method to all of them. What is this method called? It's known as the BL-Trick. Chapter 2: Overview of Re-Creating a Code The BL-Trick is a great tool to use for transferring strings of data. It can be somewhat difficult to understand, so it's best if we recreate a code I have personally made before. That way you will know in the future when to apply the BL-Trick for your own codes. We will create my "Friend Roster Plus Your Mii; Name Changer & Extender" code. It incorporates a simple BL-Trick. Let's pretend on Mario Kart Wii that you have applied a Memory Read Breakpoint at your Mii Name in dynamic memory while switching into the Friend Roster while online. The BP was hit and you end up with the following instruction + address (PAL)... Code: PAL: After some manual edits directly within the Dolphin-memory-engine, you also come to the conclusion that the Mii Name can be extended to a max of 23 characters. Now that we have an instruction address, we can use Instruction BP's for further debugging of this address if needed. If you want, feel free to boot your MKWii game if you have one available, connect to Wifi. Once you are at the Wifi Main Menu, place an Instruction BP at one of the addresses depending on the region of your game.. NTSC-U 8074BF0C PAL 8075144C NTSC-J 80750AB8 NTSC-K 8073F80C Now select 'Friends' and the emulation should pause itself due to the BP hit. Let's take a look at Code View, Registers, and Memory all at once. r4 (source register of our instruction) is outlined in red. r4 + 0x0068 points to the start of the Mii Name. The Mii Name (day1test in the supplied picture) is outlined in magenta. Mii Names are always in 16-bit ASCII in every Wii game. 16-bit ASCII is just like standard (8-bit) ASCII, but each ASCII character is a halfword to accomodate for special characters such as Japanese letters, Picture-like symbols, etc. Examples of 8 bit vs 16 bit ASCII:
Referring back to our code at hand, we need an efficient way to write out our new custom Mii Name and then replace it overwriting 'day1test'. We also want to extend the Mii name to the max of 23 characters (23 halfwords). Chapter 3: Overview of a simple BL-Trick The BL-Trick allows you to write a string of data in your source without using any PowerPC instructions. You may be wondering "How is this possible"? Let's look at a simple example of a BL Trick that will write out the word value of 0x12345678. Code: #Branch to the Label Name & Link And here is that source in compiled form (C2 code with blank address) Code: C2000000 00000002 48000009 = bl 0x8 (bl the_label) 12345678 = Our value written from scratch (.long 0x12345678) 7D8802A6 = mflr r12 As you can see the '.long' is not a PowerPC instruction. Before we go over this '.long', the bl and mflr instructions need to be explained first. Branch & Link (bl) It's similar to a standard branch instruction (b), but once the bl instruction has executed, the next address AFTER the instruction itself is placed into the Link Register. Confused? Let's go over some of photos using the above example. Here's a picture of right before the bl instruction gets executed~ You will notice there's a 'ps_msub' instruction underneath the bl instruction. This is actually the '.long 0x12345678' part. Dolphin's Code View tries to decompile every word value present in Memory. So certain contents within a BL-Trick may appear as 'legit' instructions in Code View. Here's a picture of once the bl instruction has executed (take notice the Link Register outlined in red)~ The Link Register aka the LR has been modified and now contains the address that points to the start of the BL-Trick. Here's a picture of once the 'mflr r12' instruction has executed. Blue arrow is indicating what exactly occurred in the instruction. The value in the LR was copied over to r12. r12 now points to the start of the BL-Trick. Since our BL-Trick is only one word value, r12's value is the address that points to 0x12345678. The following two instructions are responsible for copying data to/from the LR~
Chapter 4: Pseudo-Ops Code: .long 0x12345678 What is this .long? It's called a Pseudo-Op. In non-coding terms, pseudo ops are 'keywords' for your ASM Code Assembler to add in numerical values to a code without requiring the use of a PowerPC instruction. List of Pseudo-Ops:
Chapter 5: Making the code pt. 1/2 We will create a BL-Trick that contains our new extended 23-character Mii Name, and then we can use a basic Loop to copy the Mii Name from the space within our code to Dynamic Memory. With any code that involves the BL-Trick, you must be aware about the safety of the Link Register. You may have to backup up its value to a GPR (via mflr) and then move that value back to the Link Register at the end of your code (via mtlr). Let's find out if we can use the LR freely in this code. The obvious method to find out would be to look at the code's instruction address in Code View and scroll down til we find an instruction that modifies the LR. At address 8075151C is this... The instruction at the address (highlighted in blue) is 'mtlr r0'. Okay at this point we need to know what is the the closest previous instruction that modifies r0. Well we can see just 4 instructions above at address 0x8075150C is a 'lwz r0, 0x0024 (sp)' instruction. It is highlighted in blue in the picture below. We see that a value is loaded into r0, and that value is then moved to the LR. In conclusion, we can freely write to the LR without backing it up since the CPU will write a new value to the LR anyway. Referring back to the default instruction... Code: PAL: Since it's a load instruction, we want it as the last instruction of our source. That way we can freely use r5. r11 and r12 are safe to use 99% of the time. So that's 3 free registers. Alright, we should have enough free registers to use. So we won't need to use the 'Push/pop' the Stack Method. We need an instruction that will set a register to point to start of the Mii Name that is currently in dynamic memory. However, we actually want to point 2 bytes BEFORE the start of the Mii Name. Why is this? Well recall back in the Creating Loops tutorial, load and store 'updating' instructions are used. They are usually stwu (store word & update), and lwzu (load word & update). These updating type of instructions constantly increment the loading and storing addresses after each loop iteration. Since each Mii Name character is a halfword, it will make sense at some point later on in our Source to implement a loop that loads & stores a halfword for each iteration (lhzu & sthu). The loading offsets for the lhzu and instructions will be 0x2, so the loop can always continue its load+store for each individual halfword sized Mii Name character. We want to have a register point to 2 bytes before the Mii Name so when this loop goes thru its first iteration, the first Mii Name character (the 'd' in 'day1test') will be exactly loaded. With all of that being said here's the first instruction of our source. We will use r5. Code: #Need a register to point to 2 bytes before the original Mii Name Now we need to create our new 23-character Mii name using a BL-Trick. It will just a bunch of random numbers (01230123012301230123456789905). Here's the BL-Trick portion.... Code: #Use BL-Trick to write out Mii Name 01230123012301230123456789905 Okay so r12 now points to the start of the custom Mii Name. I used the .llong and .short Psuedo-Ops to give you a 'hex' view of the Mii Name. Explaining all 4 .short's~
Chapter 6: Making the code pt. 2/2 Now it's time to make that Loop that I covered about earlier~ Code: the_loop: This loop is a tiny bit different that the ones described in the Creating Loops tutorial. It's due to the fact that the custom Mii Name can vary in length, we need a way to know when any custom Mii Name has been completed transferred over to dynamic memory. There are no 16-bit ASCII characters that are a null halfword (0x0000). So a basic check against the value of 0 will work. Once the loop has been completed, the custom Mii Name will be in dynamic memory. All we need now is the code's default instruction and we're done. Let's add that in and look at the entire source. Code: #Need a register to point to 2 bytes before the original Mii Name Chapter 7: Conclusion And that's the BL Trick! Key notes about BL Tricks to wrap up this tutorial...
|