我最近开始为Xbox 360反转游戏,我真的不明白为什么%r11和%r10的内容存储在具有相同地址(0x00010000的地址[%r8]和[%r9]中)。
此代码由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
# -------------------------------------------------------------|
据我所知,您的问题是以下两行:
lis %r9, ((long_zero+0x10000)@h)
...
stw %r11, long_zero@l(%r9)
假设单词long_zero
位于地址0x1234ABCD
:
[(xxx)@h
的意思是:(xxx)
的高16位。
[0x1234ABCD + 0x10000
为0x1235ABCD
,此数字的高16位为0x1235
。
因此,指令lis %r9, ((long_zero+0x10000)@h)
等于lis %r9, 0x1235
,并将值0x12350000
加载到寄存器r9
中。
[xxx@l
的意思是:xxx
的低16位。
因此,stw %r11, long_zero@l(%r9)
等于stw %r11, 0xABCD(%r9)
。
此指令将对0xABCD
进行符号扩展(至0xFFFFABCD
),并将符号扩展的值添加到寄存器r9
中的值;结果是正在写入的地址:0x12350000 + 0xFFFFABCD = 0x1234ABCD
。
顺便说一句:我假设在汇编之前,第一条指令不是lis %r9, ((long_zero+0x10000)@h)
而是lis %r9, long_zero@ha
。
[@ha
假设低16位将被符号扩展,并且结果将在以后的一条指令(此处为stw
)中添加到寄存器中。
[这意味着如果xxx@ha
的第15位为0(因此低16位表示一个正数),则xxx@h
等于xxx
;如果第15位为1(因此,则C0]等于(xxx+0x10000)@h
。低16位代表一个负数。