1

I try to understand how the target address is calculated in a BL instruction ARMv7a.

I created a simple example program and compiled and linked it. The object file (elf) has the following instructions.

...
  14:   e3400000    movt    r0, #0
  18:   eb00000f    bl  5c <test>
  1c:   e50b0008    str r0, [fp, #-8]
...

0000005c <test>:
  5c:   e52db004    push    {fp}        ; (str fp, [sp, #-4]!)
  60:   e28db000    add fp, sp, #0

If I understand BL correct, I should get 5c as target address.

From the reference manual I found the following description:

imm32 = SignExtend(imm24:'00', 32);
targetAddress = PC + imm32;

Where imm24 are the 24 right bits of the instruction. In my case 0x000000f.

If I calculate the target address this way, I don't get 5c though.

// PC = 0x18 (where we find the BL instruction)
uint32_t imm24 = 0x00000f;
uint32_t imm32 = imm24 << 2;
// imm32 = 0x3c
uint32_t targetAddress = PC + imm32;
// targetAddress = 0x18 + 0x3c = 0x54

Do I miss something?

I used a arm-none-eabi crosscompiler with the following flags:

CFLAGS=-Wall -O0 -march=armv7-a -mtune=cortex-a7 -marm
mjspier
  • 6,386
  • 5
  • 33
  • 43
  • 2
    You maybe missed the bit about [what's actually in the PC register](http://stackoverflow.com/q/24091566/3156750)... – Notlikethat Feb 23 '16 at 12:57
  • What, people exist who read manuals and can ask a question properly? :-O – Jester Feb 23 '16 at 12:59
  • @Jester What do you not like about the question? I'm new to ARM and assembly, and even though I'm reading the manual it can happen I miss something. – mjspier Feb 23 '16 at 13:12
  • That was a compliment and you got a +1 for it ... sorry if it wasn't clear. It doesn't happen too often in the `assembly` tag that people read the manuals and come here asking if something is unclear, show what they did and ask a question properly. Crap gets tons of upvotes and you only got one. Life is not fair. – Jester Feb 23 '16 at 13:16
  • Maybe I should read comments better. lol. I tend to ask weird questions sometimes though. Thanks :D – mjspier Feb 23 '16 at 13:18

1 Answers1

2

From the ARM ARM (document number DDI 0100E):

The branch target address is calculated by:

  1. Sign-extending the 24-bit signed (two's complement) immediate to 32 bits.

  2. Shifting the result left two bits.

  3. Adding this to the contents of the PC, which contains the address of the branch instruction plus 8.

As for why this is, see 2.7.4 Prefetching and self-modifying code in the same document.

Michael
  • 57,169
  • 9
  • 80
  • 125