2

I want to decoding a blx instruction on arm, and I have found a good answer here: Decoding BLX instruction on ARM/Thumb (IOS)

But in my case, I follow this tip step by step, and get the wrong result, can anyone tell me why?

This is my test:

.plt: 000083F0  sub_83F0       ...
...
.text:00008436  FF F7 DC EF    BLX sub_83F0

I parse the machine code 'FF F7 DC EF' by follow:

   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)  
         = ?  

So the offset is 0xFFB8?
But 0x83F0-0X8436-4=0xFFB6
I need your help!!!

4

2 回答 2

3

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

  • PC在执行BLX指令期间是0x8436 + 4 == 0x843a由于 ARM 流水线
  • align(0x843a, 4) == 0x8438

所以:

  • 0x00008438 + 0ffffffb8 == 0x83f0

ARM ARM<label>在指令部分的汇编语法中提到了这一点:

对于 BLX(编码 T2、A2),汇编器计算从 BLX 指令的 Align(PC,4) 值到该标签的所需偏移值,然后选择将 imm32 设置为该偏移的编码。

对齐要求也可以通过仔细阅读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);
于 2013-07-01T06:54:02.313 回答
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
于 2013-07-01T06:58:26.500 回答