在ARM / Thumb(Android)上解码BLX指令

时间:2013-07-01 06:10:46

标签: arm

我想在手臂上解码一个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
我需要你的帮助!!!

2 个答案:

答案 0 :(得分:2)

当BLX的目标是32位ARM代码时,BLX指令中编码的立即值将添加到align(PC,4),而不是PC的原始值。

    由于ARM管道,执行PC指令期间
  • BLX0x8436 + 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