I want to hand-assemble a BL <target> instruction for the ARM family of processors. I am experimenting with a Raspberry OS Pi 3+, but would eventually use it on a Cortex M0+ (Pico).
I have tried understanding it from the ARM manuals, but only get close. Specifically the A 7.1.17 section of the ARM architecture reference.
Here is my effort so far. Specifically, I need to get the macro_bl macro working in the following example:
asmtests.s:
.syntax unified
.thumb_func
.text
.global _start
.macro macro_bl target
.hword (((\target - . - 4) >> 11) & 0x07ff) | 0x0f000
.hword (((\target - . - 2)) & 0x07ff) | 0x0f800
.endm
.align 2
before: nop
.skip 0x00300000
_start:
bl before
bl before
macro_bl before
bl before
bl after
bl after
macro_bl after
bl after
.align 2
.skip 0x00300000
after:
nop
I assemble it using as -al asmtests.s -o asmtests.o
And the assembly listing looks like this:
1 .syntax unified
2 .thumb_func
3
4 .text
5 .global _start
6
7 .macro macro_bl target
8 .hword (((\target - . - 4) >> 11) & 0x07ff) | 0x0f000
9 .hword (((\target - . - 2)) & 0x07ff) | 0x0f800
10 .endm
11
12 .align 2
13 0000 C046 before: nop
14 0002 00000000 .skip 0x00300000
14 00000000
14 00000000
14 00000000
14 00000000
15
16 _start:
17 300002 FFF4FDFF bl before
18 300006 FFF4FBFF bl before
19 30000a FFF1F2FF macro_bl before
20 30000e FFF4F7FF bl before
21
22 300012 00F307F8 bl after
23 300016 00F305F8 bl after
24 30001a 00F606F8 macro_bl after
25 30001e 00F301F8 bl after
26
27 300022 C046 .align 2
28 300024 00000000 .skip 0x00300000
28 00000000
28 00000000
28 00000000
28 00000000
29 after:
30 600024 C046C046 nop
Line 29:
30000a FFF1F2FF macro_bl before
I expect it to be
30000a FFF4F9FF macro_bl before
and on line 24
30001a 00F606F8 macro_bl after
to be
30001a 00F303F8 macro_bl after
I have tried minor variations in the macro, such as shifting by 12 instead of 11, and it works for some values of offset controlled by the space reserved for the labels before and after, not for others.
Some answers on SO explain how the processor(s) use it, I would be grateful if someone can help me create the macro that shows this.
I understand the range of jumps vary processor to processor, but if I get the gist of the macro working, it would help