assembly - (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
# -------------------------------------------------------------|
解决方案
据我正确理解你,你的问题是以下两行:
lis %r9, ((long_zero+0x10000)@h)
...
stw %r11, long_zero@l(%r9)
让我们假设这个词long_zero
位于地址0x1234ABCD
:
(xxx)@h
表示: 的高 16 位(xxx)
。
0x1234ABCD + 0x10000
is0x1235ABCD
和这个数字的高 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@h
xxx
(xxx+0x10000)@h
推荐阅读
- javascript - 防止特定子元素在 jQuery 中触发父鼠标悬停事件
- c# - Google Pay 集成显示此付款选项在此应用中不再可用
- r - checkboxGroupInput 过滤数据
- ios - 如何通过我可以访问的所有 NSUserDefaults 套件获取数组/循环?
- excel - vlookup,如果值不存在检查另一列 - Excel
- android - 读取并通知BLE android
- ios - 为什么 UIView.isHidden = false 的动画调用是复合的?
- php - XML 子元素不会被添加,但不会在 PHP 中引发任何错误
- javascript - 有没有什么方法可以导入 ES 模块的一部分而没有副作用?
- sql - Netsuite 案例声明