We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello,
I found the arm assembler always does an extra `plus 4` when calculating the label of instruction B. (support-board: nrf52840dk, architecture; Cortex-M ), but the armv7-M document (ARM DDI 0403E.e) doesn't mention it ? could you please give me some suggestions?
Considering the following example:
1) `0x01, 0xdb` (i.e. 0xdb01) corresponds to the encoding T1 of B with cond = LT and imm8=0x01
1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 --------------------------------|1 1 0 1| cond | imm8 | --------------------------------
2) computing label
according to the description "if cond == '1110' then SEE UDF;if cond == '1111' then SEE SVC;imm32 = SignExtend(imm8:'0', 32);if InITBlock() then UNPREDICTABLE;"
we know imm32 = 0x00000002
according to the description "
Operationif ConditionPassed() thenEncodingSpecificOperations();BranchWritePC(PC + imm32);
"
and "
////BranchWritePC()==========
BranchWritePC(bits(32) address)
BranchTo(address<31:1>:’0’);
////BranchTo()==========BranchTo(bits(32) address)_R[RName_PC] = address;return;
we know the label should be "pc+2", but in practise, the label is "pc+6", I tested it on my board:
```C
//
#include <stdio.h>#include <string.h>#include <stdint.h>
__attribute__((aligned(4))) unsigned char code[] = { 0x01, 0xdb, 0x40, 0xf2, 0x0b, 0x0b, 0xcc, 0xf8, 0x06, 0xb0, 0x32, 0xdb, 0x25, 0xfa, 0x04, 0xf5, 0x40, 0xf2, 0x2a, 0x00, 0x70, 0x47, 0x40, 0xf2, 0x3a, 0x00, 0x70, 0x47};
/* 0x00, 0xdb, 0x40, 0xf2, 0x0b, 0x0b, 0xcc, 0xf8, 0x06, 0xb0, 0x32, 0xdb, 0x25, 0xfa, 0x04, 0xf5, ===> b always +4??? (0+4) 0x20000200 <code> blt.n 0x20000204 <code+4>0x20000202 <code+2> movw r11, #110x20000206 <code+6> str.w r11, [r12, #6]0x2000020a <code+10> blt.n 0x20000272 <impure_data+78>0x2000020c <code+12> lsr.w r5, r5, r4
*/
/* 0x01, 0xdb ... ===> b always +4??? (2+4) 0x20000200 <code> blt.n 0x20000206 <code+6> */
int main(void) { int i; __asm volatile ("orr %[input_0], #0x1\n\t" "blx %[input_0]\n\t" "mov r1, r0\n\t" : [result] "=r" (i) : [input_0] "r" (code) : ); printf("get this done. returned: %d\n", i);
return 0;}
```
I just found this description "Calculate the PC or Align(PC,4) value of the instruction. The PC value of an instruction is its address plus 4for a Thumb instruction. The Align(PC,4) value of an instruction is its PC value ANDed with 0xFFFFFFFC toforce it to be word-aligned. (A4-104)", so maybe because Thumb adopts a different PC calculation?