首页 > 解决方案 > (PowerPC) 不明白为什么代码将寄存器的内容存储在同一个地址

问题描述

最近开始为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
# -------------------------------------------------------------|

标签: assemblypowerpcxbox360

解决方案


据我正确理解你,你的问题是以下两行:

lis     %r9, ((long_zero+0x10000)@h)
...
stw     %r11, long_zero@l(%r9)

让我们假设这个词long_zero位于地址0x1234ABCD

(xxx)@h表示: 的高 16 位(xxx)

0x1234ABCD + 0x10000is0x1235ABCD和这个数字的高 16 位是0x1235

因此,该指令lis %r9, ((long_zero+0x10000)@h)等于lis %r9, 0x1235并将值加载0x12350000到寄存器r9中。

xxx@l表示: 的低 16 位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指令中添加到寄存器中。

这意味着如果第15 位为 0(因此低 16 位表示正数),则等于xxx@ha如果第 15 位为 1(因此低 16 位表示负数)。xxx@hxxx(xxx+0x10000)@h


推荐阅读