【问题标题】:(PowerPC) Do not understand why the code stores contents of registers in the same address(PowerPC) 不明白为什么代码将寄存器的内容存储在同一个地址
【发布时间】:2020-06-09 02:31:45
【问题描述】:

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

【问题讨论】:

  • 它们被存储到不同的地址,因为一个使用long_zero@l作为偏移量,另一个使用long_zero_1@l作为偏移量。
  • 您的意思是long_zero@l(%r9) 将改为address of long_zero + 0 + [%r9]

标签: assembly powerpc xbox360


【解决方案1】:

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

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

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

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

0x1234ABCD + 0x100000x1235ABCD,这个数字的高 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,则xxx@ha 等于 xxx@h(因此低 16 位表示正数),如果第 15 位为 1,则它等于 (xxx+0x10000)@h(因此低 16 位表示负数)。

【讨论】:

  • 为什么正数 0xABCD 扩展到 0xFFFFABCD?不应该是0x0000ABCD,因为二进制形式的正数以0开头,负数以1开头?
  • @AkmubiLin 0xABCD 将是二进制形式的 1010101111001101。所以第一位是“1”。请注意,您必须知道位数才能判断数字是正数还是负数。 16 位数字0xABC 为正数; 12 位数字0xABC 将是负数。 PowerPC 指令通常采用 16 位数字。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 2018-10-22
相关资源
最近更新 更多