I recently started reversing the game for the Xbox 360, and I really don’t understand why the contents of %r11 and %r10 are stored in the addresses [%r8] and [%r9] that have the same address (0x00010000).
This code generated by IDA.
.globl _start
_start:
.set var_1F0, -0x1F0
.long_zero: .long 0
.long_zero_1: .long 0
mflr %r12 # Move from link register
bl sub_831A8168 # Branch
addi %r31, %sp, var_1F0 # Add Immediate
stwu %sp, -0x1F0(%sp) # Store Word with Update
nop # No Operation
# -------------------------------------------------------------|
mr %r8, %r8 # Move Register
mr %r8, %r8 # Move Register
lis %r9, ((long_zero+0x10000)@h) # Load Immediate Shifted
lis %r8, ((long_zero_1+0x10000)@h) # Load Immediate Shifted
li %r11, -1 # Load Immediate
li %r10, -1 # Load Immediate
stw %r11, long_zero@l(%r9) # Store Word
stw %r10, long_zero_1@l(%r8) # Store Word
# -------------------------------------------------------------|
As far as I undestand you correctly, your problem are the following two lines:
lis %r9, ((long_zero+0x10000)@h)
...
stw %r11, long_zero@l(%r9)
Let's assume that the word long_zero
is located at the address 0x1234ABCD
:
(xxx)@h
means: The high 16 bits of (xxx)
.
0x1234ABCD + 0x10000
is 0x1235ABCD
and the high 16 bits of this number are 0x1235
.
Therefore, the instruction lis %r9, ((long_zero+0x10000)@h)
is equal to lis %r9, 0x1235
and will load the value 0x12350000
into register r9
.
xxx@l
means: The low 16 bits of xxx
.
For this reason stw %r11, long_zero@l(%r9)
is equal to stw %r11, 0xABCD(%r9)
.
This instruction will sign-extend 0xABCD
(to 0xFFFFABCD
) and add the sign-extended value to the value in register r9
; the result is the address being written: 0x12350000 + 0xFFFFABCD = 0x1234ABCD
.
By the way: I assume that the first instruction was not lis %r9, ((long_zero+0x10000)@h)
but lis %r9, long_zero@ha
before being assembled.
@ha
assumes that the low 16 bits will be sign-extended and the result will be added to the register in a later (here: stw
) instruction.
This means that xxx@ha
is equal to xxx@h
if bit 15 of xxx
is 0 (so the low 16 bits represent a positive number) and it is equal to (xxx+0x10000)@h
if bit 15 is 1 (so the low 16 bits represent a negative number).