
!
!
You must login or register to view this content.
[default_mp.elf]
efault' and press OK
!
r0 = old link register, i won't talk about it for now
r1 = stack pointer, i won't talk about it for now
r2 = table of contents pointer, i won't talk about it for now
r3 = it can be used as the first argument of a function OR as the returned value from a function
r4–r10 = Used as the 2nd to the 8th arguments of a function.
r11 = used for the PS3 Syscalls
r12 = local var
r13-r31 = global var, we use them to store a value and being able to use it later on another function.

int a = 10;
string b = "Bad Luck Brian";
byte[] c = new byte[] {0x05, 0x02, 0xFF};
li r3, 0x1500 ::: r3 = 00 00 15 00
lis r3, 0x26 ::: r3 = 00 26 00 00
lis r3, 0x2600 ::: r3 = 26 00 00 00
lis r3, 0x216 ::: r3 = 02 16 00 00
addic RESULT, REGISTER, VALUE
li r3, 0x15
addic r3, r3, 0x01
FCA2801
FCA28 01
FCA 28 01
F CA 28 01
to reach the XX XX YY YY format
*************
*XX XX YY YY*
*0F CA 28 01*
*************
lis r3, 0x0FCA //r3 = 0F CA 00 00
addic r3, r3, 0x2801 //r3 = 0F CA 00 00 + 00 00 28 01 (0F CA 28 01)
1d60c
1d6 0c
1 d6 0c
01 d6 0c
00 01 d6 0c
*************
*XX XX YY YY*
*00 01 d6 0c*
*************
lis r3, 0x0001 //r3 = 00 01 00 00
addic r3, r3, 0xD60C //r3 = 00 01 00 00 + 00 00 D6 0C (00 01 D6 0C )
r3 = 0x0001D60c or 0x1D60c

lbz (1 byte)
lhz (2 bytes)
lwz (4 bytes)
ld (8 bytes)
lwz RESULT, ADDRESS, TEMP_VAL
Result = register containing the byte at the address
ADDRESS = register containing the address to read from
TEMP_VAL= we can use it as a temporary 'addic'
lis r3, 0xff r3 = 00 ff 00 00 (0xff0000)
addic r3, r3, 0x1234 r3 = 00 ff 12 34 (0xff1234)
lwz r4, r3, 0 r4 = the first 4 bytes at 0xff1234
lis r3, 0xff
lwz r4, r3, 0x1234 <- we use it as a temporary addic to save a line !!! but WARNING: on the next line r3 will be restored to 00 ff 00 00 while
using addic make it permanent !!!!
lis r3, 0x0110
lwz r4, r3, 0xd60c
lis r3, 0x0110
addic r3,r3, 0xd60c
lwz r4, r3, 0
stb (1 byte)
sth (2 bytes)
stw (4 bytes)
std (8 bytes)
stw VALUE, ADDRESS, TEMP_VAL
lis r3, 0x210 (0x2100000) || 02 10 00 00
li r4, 0x15
stw r4, r3, 0
lis r3, 0xFC (r3 = 00 FC 00 00)
li r4. 0x15
stw r4, r3, 0xA280 (0xFCA280)
li r3, 0x15
cmpwi r3, 0x19
-eq = 0 (false, they're not equal)
-lt = 1 (true, 0x15 is lesser than 0x19 )
-gt = 0 (false, 0x15 is not greater than 0x19)
li r3, 0x15
cmpwi r3, 0x15
-eq = 1 (true, they're equal)
-lt = 0 (false, 0x15 is not lesser than 0x15 )
-gt = 0 (false, 0x15 is not greater than 0x15)
b - jumps no matter what
beq - jumps if -eq = 1
bne - jumps if -eq = 0
bgt - jumps if -gt = 1
blt - jumps if -lt = 1
0: li r3, 0x20 //set r3 to: 00 00 00 15
4: cmpwi r3, 0x30 // -eq:0 -gt:0 -lt:1
8: beq 28 //it will not jump to :28 because -eq is false, so the program will continue to the next line ( :C)
C: bgt 28 //it will not jump to :28 because -lt is false, so the program will continue to the next line ( :10 )
10: b 14 // jump to :14
14: bne 1C //will jump to 1C because -eq = 0
18: b 28 //this will never be executed
1C: b 28 //it will jump to :28
20: li r3, 0x1234 //not executed
24: li r3, 0x1234 //not executed
28: b 0 //jump back to 0 for an infinite loop, yeah
!
0x12340000 = my string
0x55550000 = pointer
*ADDRESS | *BYTES* | ASCII
0x12340000: 55 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
...
0x55550000: 42 61 64 20 4C 75 63 6B 20 42 72 69 61 6E 00 00 Bad Luck Brian..
lis r3, 0x1234
lwz r3, 0x12340000(r3)
//0x2100000 = pointer to call
//read memory to get your arguments using lwz
lis r9, 0x210 (0x2100000) //time to load the address
mtctr r9 //this will save the address in a special register (count register), will talk about it in the next lesson
bctrl //this will call the address in the count register, will talk about it in the next lesson

//0x2100000 contains: 00 12 34 56 (0x123456),
//0x123456 = function i wanna call
lis r3, 0x210 //loads the address: 0x2100000 in r3
lwz r3, r3 //read at: 0x2100000 and store the value in r3 (4 bytes)
mtctr r3 //store r3 in the count register
bctrl //call the value in the count register

lis r3, 0xFF1 <- it will be written in 4 bytes (3c 60 0f f1) <- will explain soon
li = 0x38
lis = 0x3C
addic = 0x30
stb = 0x98
stw = 0x90
std = 0xF8
lbz = 0x88
lwz = 0x80
ld = 0xE8
cmpwi = 0x2C
b = 0x48 or 0x4B
bl = 0x48 or 0x4B
beq = 0x41, 0x82
bne = 0x40, 0x82
blt = 0x41, 0x80
bgt = 0x41, 0x81
mtctr = 0x7C, 0x69, 0x03, 0xA6
bctrl = 0x4E, 0x80, 0x04, 0x21
38 XX VV VV
38 = opcode
XX = Register to load the value into
VV VV = value to load in the register
r0: 38 00 VV VV
r1: 38 20 VV VV
r2: 38 40 VV VV
r3: 38 60 VV VV
r4: 38 80 VV VV
r5: 38 A0 VV VV
r6: 38 C0 VV VV
r7: 38 F0 VV VV
r8: 39 00 VV VV
r9: 39 20 VV VV
r10: 39 40 VV VV
r11: 39 60 VV VV
r12: 39 80 VV VV

r0: 3C 00 VV VV
r1: 3C 20 VV VV
r2: 3C 40 VV VV
r3: 3C 60 VV VV
r4: 3C 80 VV VV
r5: 3C A0 VV VV
r6: 3C C0 VV VV
r7: 3C F0 VV VV
r8: 3D 00 VV VV
r9: 3D 20 VV VV
r10: 3D 40 VV VV
r11: 3D 60 VV VV
r12: 3D 80 VV VV
30 XY VV VV
38 = opcode
X = Register that will contain the result of the addition
Y = Register that were going to add to the value
VV VV = value to add to Y
addic r3, r4, 0xFF || 30 64 00 FF
addic r12, r4, 0xFF || 31 84 00 FF
addic r3, r10, 0xFF || 30 6A 00 FF || 10 = 0x0A (hexadecimal)
stb = 0x98 // 0x99 for r8+
stw = 0x90 // 0x91 for r8+
std = 0xF8 // 0xF9 for r8+
90 XY VV VV
X = register that will be sent in the memory (VALUE)
Y = register of the address that will receive the VALUE (X)
VV VV = Temporary value to add to the address (Y)
lis r3, 0x2100000 || 3C 60 02 10
li r4, 0x15 || 38 80 00 15
stw r4, r3, 0x2101234 || 90 83 12 34
//ON THIS LINE, r3 RESETS BACK TO: 0x2100000 !!!
lbz = 0x88 // 0x89 for r8+
lwz = 0x80 // 0x81 for r8+
ld = 0xE8 // 0xE9 for r8+
80 XY VV VV
It works like stw !!!
X = register that will contain the value read from the memory
Y = register of the address that will be read
VV VV = Temporary value to add to the address (Y)
lis r3, 0x2100000 || 3C 60 02 10
li r4, 0x15 || 38 80 00 15
lwz r4, r3, 0x2101234 || 80 83 12 34
//ON THIS LINE, r3 RESETS BACK TO: 0x2100000 AND r4 = the first bytes that was at: 0x2101234 !!!
cmpwi = 0x2C
2c 0Y VV VV
0 = keep it as 0
Y = Register to compare, we just put its number in hex
VV VV = value that the register will be compared with
cmpwi r3, 0x55 || 2c 03 00 55
cmwpi r12, 0x55 || 2c 0C 00 55 //0x0C = 12 in hexadecimal
b = 0x48 or 0x4B
bl = 0x48 or 0x4B
beq = 0x41, 0x82
bne = 0x40, 0x82
blt = 0x41, 0x80
bgt = 0x41, 0x81
48/4B XX XX XX
XX XX XX = difference between current position and the location we want to jump to
41 82 XX XX
XX XX = difference between current position and the location we want to jump to
also, to use bl we add +1 to the difference !!
0x11010: bl 0x11050 || 48 00 00 41
...
0x11050: //function...
mtctr r4 || 7C 89 03 A6
mtctr r12 || 7D 89 03 A6
bctr 4E 80 04 20
bctrl 4E 80 04 21

but i miss the relation to a game maybe CoD Ghosts. Would be awesome when you would explain how to find some offsets or so
)
!
!
You must login or register to view this content.
[default_mp.elf]
efault' and press OK
!
r0 = old link register, i won't talk about it for now
r1 = stack pointer, i won't talk about it for now
r2 = table of contents pointer, i won't talk about it for now
r3 = it can be used as the first argument of a function OR as the returned value from a function
r4–r10 = Used as the 2nd to the 8th arguments of a function.
r11 = used for the PS3 Syscalls
r12 = local var
r13-r31 = global var, we use them to store a value and being able to use it later on another function.

int a = 10;
string b = "Bad Luck Brian";
byte[] c = new byte[] {0x05, 0x02, 0xFF};
li r3, 0x1500 ::: r3 = 00 00 15 00
lis r3, 0x26 ::: r3 = 00 26 00 00
lis r3, 0x2600 ::: r3 = 26 00 00 00
lis r3, 0x216 ::: r3 = 02 16 00 00
addic RESULT, REGISTER, VALUE
li r3, 0x15
addic r3, r3, 0x01
FCA2801
FCA28 01
FCA 28 01
F CA 28 01
to reach the XX XX YY YY format
*************
*XX XX YY YY*
*0F CA 28 01*
*************
lis r3, 0x0FCA //r3 = 0F CA 00 00
addic r3, r3, 0x2801 //r3 = 0F CA 00 00 + 00 00 28 01 (0F CA 28 01)
1d60c
1d6 0c
1 d6 0c
01 d6 0c
00 01 d6 0c
*************
*XX XX YY YY*
*00 01 d6 0c*
*************
lis r3, 0x0001 //r3 = 00 01 00 00
addic r3, r3, 0xD60C //r3 = 00 01 00 00 + 00 00 D6 0C (00 01 D6 0C )
r3 = 0x0001D60c or 0x1D60c

lbz (1 byte)
lhz (2 bytes)
lwz (4 bytes)
ld (8 bytes)
lwz RESULT, ADDRESS, TEMP_VAL
Result = register containing the byte at the address
ADDRESS = register containing the address to read from
TEMP_VAL= we can use it as a temporary 'addic'
lis r3, 0xff r3 = 00 ff 00 00 (0xff0000)
addic r3, r3, 0x1234 r3 = 00 ff 12 34 (0xff1234)
lwz r4, r3, 0 r4 = the first 4 bytes at 0xff1234
lis r3, 0xff
lwz r4, r3, 0x1234 <- we use it as a temporary addic to save a line !!! but WARNING: on the next line r3 will be restored to 00 ff 00 00 while
using addic make it permanent !!!!
lis r3, 0x0110
lwz r4, r3, 0xd60c
lis r3, 0x0110
addic r3,r3, 0xd60c
lwz r4, r3, 0
stb (1 byte)
sth (2 bytes)
stw (4 bytes)
std (8 bytes)
stw VALUE, ADDRESS, TEMP_VAL
lis r3, 0x210 (0x2100000) || 02 10 00 00
li r4, 0x15
stw r4, r3, 0
lis r3, 0xFC (r3 = 00 FC 00 00)
li r4. 0x15
stw r4, r3, 0xA280 (0xFCA280)
li r3, 0x15
cmpwi r3, 0x19
-eq = 0 (false, they're not equal)
-lt = 1 (true, 0x15 is lesser than 0x19 )
-gt = 0 (false, 0x15 is not greater than 0x19)
li r3, 0x15
cmpwi r3, 0x15
-eq = 1 (true, they're equal)
-lt = 0 (false, 0x15 is not lesser than 0x15 )
-gt = 0 (false, 0x15 is not greater than 0x15)
b - jumps no matter what
beq - jumps if -eq = 1
bne - jumps if -eq = 0
bgt - jumps if -gt = 1
blt - jumps if -lt = 1
0: li r3, 0x20 //set r3 to: 00 00 00 15
4: cmpwi r3, 0x30 // -eq:0 -gt:0 -lt:1
8: beq 28 //it will not jump to :28 because -eq is false, so the program will continue to the next line ( :C)
C: bgt 28 //it will not jump to :28 because -lt is false, so the program will continue to the next line ( :10 )
10: b 14 // jump to :14
14: bne 1C //will jump to 1C because -eq = 0
18: b 28 //this will never be executed
1C: b 28 //it will jump to :28
20: li r3, 0x1234 //not executed
24: li r3, 0x1234 //not executed
28: b 0 //jump back to 0 for an infinite loop, yeah
!
0x12340000 = my string
0x55550000 = pointer
*ADDRESS | *BYTES* | ASCII
0x12340000: 55 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
...
0x55550000: 42 61 64 20 4C 75 63 6B 20 42 72 69 61 6E 00 00 Bad Luck Brian..
lis r3, 0x1234
lwz r3, 0x12340000(r3)
//0x2100000 = pointer to call
//read memory to get your arguments using lwz
lis r9, 0x210 (0x2100000) //time to load the address
mtctr r9 //this will save the address in a special register (count register), will talk about it in the next lesson
bctrl //this will call the address in the count register, will talk about it in the next lesson

//0x2100000 contains: 00 12 34 56 (0x123456),
//0x123456 = function i wanna call
lis r3, 0x210 //loads the address: 0x2100000 in r3
lwz r3, r3 //read at: 0x2100000 and store the value in r3 (4 bytes)
mtctr r3 //store r3 in the count register
bctrl //call the value in the count register

lis r3, 0xFF1 <- it will be written in 4 bytes (3c 60 0f f1) <- will explain soon
li = 0x38
lis = 0x3C
addic = 0x30
stb = 0x98
stw = 0x90
std = 0xF8
lbz = 0x88
lwz = 0x80
ld = 0xE8
cmpwi = 0x2C
b = 0x48 or 0x4B
bl = 0x48 or 0x4B
beq = 0x41, 0x82
bne = 0x40, 0x82
blt = 0x41, 0x80
bgt = 0x41, 0x81
mtctr = 0x7C, 0x69, 0x03, 0xA6
bctrl = 0x4E, 0x80, 0x04, 0x21
38 XX VV VV
38 = opcode
XX = Register to load the value into
VV VV = value to load in the register
r0: 38 00 VV VV
r1: 38 20 VV VV
r2: 38 40 VV VV
r3: 38 60 VV VV
r4: 38 80 VV VV
r5: 38 A0 VV VV
r6: 38 C0 VV VV
r7: 38 F0 VV VV
r8: 39 00 VV VV
r9: 39 20 VV VV
r10: 39 40 VV VV
r11: 39 60 VV VV
r12: 39 80 VV VV

r0: 3C 00 VV VV
r1: 3C 20 VV VV
r2: 3C 40 VV VV
r3: 3C 60 VV VV
r4: 3C 80 VV VV
r5: 3C A0 VV VV
r6: 3C C0 VV VV
r7: 3C F0 VV VV
r8: 3D 00 VV VV
r9: 3D 20 VV VV
r10: 3D 40 VV VV
r11: 3D 60 VV VV
r12: 3D 80 VV VV
30 XY VV VV
38 = opcode
X = Register that will contain the result of the addition
Y = Register that were going to add to the value
VV VV = value to add to Y
addic r3, r4, 0xFF || 30 64 00 FF
addic r12, r4, 0xFF || 31 84 00 FF
addic r3, r10, 0xFF || 30 6A 00 FF || 10 = 0x0A (hexadecimal)
stb = 0x98 // 0x99 for r8+
stw = 0x90 // 0x91 for r8+
std = 0xF8 // 0xF9 for r8+
90 XY VV VV
X = register that will be sent in the memory (VALUE)
Y = register of the address that will receive the VALUE (X)
VV VV = Temporary value to add to the address (Y)
lis r3, 0x2100000 || 3C 60 02 10
li r4, 0x15 || 38 80 00 15
stw r4, r3, 0x2101234 || 90 83 12 34
//ON THIS LINE, r3 RESETS BACK TO: 0x2100000 !!!
lbz = 0x88 // 0x89 for r8+
lwz = 0x80 // 0x81 for r8+
ld = 0xE8 // 0xE9 for r8+
80 XY VV VV
It works like stw !!!
X = register that will contain the value read from the memory
Y = register of the address that will be read
VV VV = Temporary value to add to the address (Y)
lis r3, 0x2100000 || 3C 60 02 10
li r4, 0x15 || 38 80 00 15
lwz r4, r3, 0x2101234 || 80 83 12 34
//ON THIS LINE, r3 RESETS BACK TO: 0x2100000 AND r4 = the first bytes that was at: 0x2101234 !!!
cmpwi = 0x2C
2c 0Y VV VV
0 = keep it as 0
Y = Register to compare, we just put its number in hex
VV VV = value that the register will be compared with
cmpwi r3, 0x55 || 2c 03 00 55
cmwpi r12, 0x55 || 2c 0C 00 55 //0x0C = 12 in hexadecimal
b = 0x48 or 0x4B
bl = 0x48 or 0x4B
beq = 0x41, 0x82
bne = 0x40, 0x82
blt = 0x41, 0x80
bgt = 0x41, 0x81
48/4B XX XX XX
XX XX XX = difference between current position and the location we want to jump to
41 82 XX XX
XX XX = difference between current position and the location we want to jump to
also, to use bl we add +1 to the difference !!
0x11010: bl 0x11050 || 48 00 00 41
...
0x11050: //function...
mtctr r4 || 7C 89 03 A6
mtctr r12 || 7D 89 03 A6
bctr 4E 80 04 20
bctrl 4E 80 04 21

Copyright © 2026, NextGenUpdate.
All Rights Reserved.