Assembling the BL <target> instruction in thumb mode

79 Views Asked by At

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

0

There are 0 best solutions below