我想在手臂上解码一个blx指令,我在这里找到了一个很好的答案: Decoding BLX instruction on ARM/Thumb (IOS)
但在我的情况下,我一步一步地遵循这个提示,并得到错误的结果,有人可以告诉我为什么吗?
这是我的测试:
.plt: 000083F0 sub_83F0 ...
...
.text:00008436 FF F7 DC EF BLX sub_83F0
我通过以下方式解析机器代码'FF F7 DC EF':
F7 FF EF DC
11110 1 1111111111 11 1 0 1 1111101110 0
S imm10H J1 J2 imm10L
I1 = NOT(J1 EOR S) = 1
I2 = NOT(J2 EOR S) = 1
imm32 = SignExtend(S:I1:I2:imm10H:imm10L:00)
= SignExtend(1111111111111111110111000)
= SignExtend(0x1FFFFB8)
= ?
所以偏移量是0xFFB8?
但是0x83F0-0X8436-4 = 0xFFB6
我需要你的帮助!!!
答案 0 :(得分:2)
当BLX的目标是32位ARM代码时,BLX
指令中编码的立即值将添加到align(PC,4)
,而不是PC
的原始值。
PC
指令期间BLX
为0x8436 + 4 == 0x843a
align(0x843a, 4) == 0x8438
所以:
0x00008438 + 0ffffffb8 == 0x83f0
ARM ARM在指令的<label>
部分的汇编语法中提到了这一点:
对于BLX(编码T2,A2),汇编程序计算从BLX指令的Align(PC,4)值到此标签的偏移量所需的值,然后选择将imm32设置为该偏移量的编码。 / p>
通过仔细阅读ARM ARM中的Operation伪代码,也可以找到对齐要求:
if ConditionPassed() then
EncodingSpecificOperations();
if CurrentInstrSet == InstrSet_ARM then
next_instr_addr = PC - 4;
LR = next_instr_addr;
else
next_instr_addr = PC;
LR = next_instr_addr<31:1> : ‘1’;
if toARM then
SelectInstrSet(InstrSet_ARM);
BranchWritePC(Align(PC,4) + imm32); // <--- alignment of the current PC when BLX to non-Thumb ARM code
else
SelectInstrSet(InstrSet_Thumb);
BranchWritePC(PC + imm32);
答案 1 :(得分:0)
F7FF
1111011111111111
111 10 11111111111 h = 10 offset upper = 11111111111
EFDC
1110111111011100
111 01 11111011100 h = 01 blx offset upper 11111011100
offset = 1111111111111111011100<<1
sign extended = 0xFFFFFFB8
0x00008436 + 2 + 0xFFFFFFB8 = 1000083F0
clip to 32 bits 0x000083F0