(PowerPC) 不明白为什么代码把寄存器的内容存放在同一个地址
(PowerPC) Do not understand why the code stores contents of registers in the same address
我最近开始在Xbox 360上逆向游戏,实在不明白为什么%r11和%r10的内容存放在地址[%r8]和[%r9]相同的地方地址 (0x00010000).
此代码由 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
的第15位为0(因此低16位代表正数),则xxx@ha
等于xxx@h
并且等于(xxx+0x10000)@h
如果第 15 位为 1(因此低 16 位表示负数)。
我最近开始在Xbox 360上逆向游戏,实在不明白为什么%r11和%r10的内容存放在地址[%r8]和[%r9]相同的地方地址 (0x00010000).
此代码由 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)
.
0x1234ABCD + 0x10000
是0x1235ABCD
这个数的高16位是0x1235
.
因此,指令lis %r9, ((long_zero+0x10000)@h)
等于lis %r9, 0x1235
并将值0x12350000
加载到寄存器r9
。
xxx@l
表示:xxx
.
因此 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
的第15位为0(因此低16位代表正数),则xxx@ha
等于xxx@h
并且等于(xxx+0x10000)@h
如果第 15 位为 1(因此低 16 位表示负数)。