assembly ARM 7a指令-没有为立即数定义分支BX(相对位移),有什么替代方法?

czfnxgou  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(132)

我正在修改一个汇编器/链接器来添加一个ARM 7a后端。为了与一个调用(BL)交互工作,有BLX,所以如果我看到一个设置了位0的全局符号,我知道要将BL切换到BLX指令。
但是对于分支,没有BX可用于立即数(相对位移),只有寄存器定位地址。
我没有看到一个单一的指令替代,所以我使用单板-分支到一个LDR r0, [pc + offset],它加载的符号地址从一个.word,然后BX r0
但我不相信这对于一个非常常见的操作来说是真的必要的--分支到一个碰巧用thumb代码编写的函数。链接器必须以某种方式处理包含泛型B指令的目标代码,这些指令最终被指定用于thumb模式代码。
所以我的问题是:链接器是如何处理的呢?

eqqqjvef

eqqqjvef1#

因此C:

void thumb_fun(void);
void arm_fun ( void )
{
    thumb_fun();
}

x.s:

.thumb

    bl arm_fun
    b .

.globl thumb_fun
.thumb_func
thumb_fun:
    bx lr

构建和反汇编:

Disassembly of section .text:

00001000 <thumb_fun-0x6>:
    1000:   f000 f80a   bl  1018 <__arm_fun_from_thumb>
    1004:   e7fe        b.n 1004 <thumb_fun-0x2>

00001006 <thumb_fun>:
    1006:   4770        bx  lr

00001008 <arm_fun>:
    1008:   e92d4010    push    {r4, lr}
    100c:   eb000003    bl  1020 <__thumb_fun_from_arm>
    1010:   e8bd4010    pop {r4, lr}
    1014:   e12fff1e    bx  lr

00001018 <__arm_fun_from_thumb>:
    1018:   4778        bx  pc
    101a:   e7fd        b.n 1018 <__arm_fun_from_thumb>
    101c:   eafffff9    b   1008 <arm_fun>

00001020 <__thumb_fun_from_arm>:
    1020:   e59fc000    ldr ip, [pc]    ; 1028 <__thumb_fun_from_arm+0x8>
    1024:   e12fff1c    bx  ip
    1028:   00001007    .word   0x00001007
    102c:   00000000    .word   0x00000000

如果我用--use-blx链接

Disassembly of section .text:

00008000 <thumb_fun-0x6>:
    8000:   f000 e802   blx 8008 <arm_fun>
    8004:   e7fe        b.n 8004 <thumb_fun-0x2>

00008006 <thumb_fun>:
    8006:   4770        bx  lr

00008008 <arm_fun>:
    8008:   ea000000    b   8010 <__thumb_fun_from_arm>
    800c:   00000000    andeq   r0, r0, r0

00008010 <__thumb_fun_from_arm>:
    8010:   e51ff004    ldr pc, [pc, #-4]   ; 8014 <__thumb_fun_from_arm+0x4>
    8014:   00008007    .word   0x00008007

我现在没有一个带链接器的llvm,它需要很长的时间来构建。我认为它是类似的。
我认为正如评论中所回答的那样,ABI为这样的事情保留了一个寄存器。
如果我没记错的话,blx在早期的内核中有问题,所以工具没有使用它。
我在这台机器上完成了armv 4 t的clang构建。

Disassembly of section .text:

000200e4 <thumb_fun-0x6>:
   200e4:   f000 e802   blx 200ec <arm_fun>
   200e8:   e7fe        b.n 200e8 <thumb_fun-0x2>

000200ea <thumb_fun>:
   200ea:   4770        bx  lr

000200ec <arm_fun>:
   200ec:   eaffffff    b   200f0 <__ARMv5ABSLongThunk_thumb_fun>

000200f0 <__ARMv5ABSLongThunk_thumb_fun>:
   200f0:   e51ff004    ldr pc, [pc, #-4]   ; 200f4 <__ARMv5ABSLongThunk_thumb_fun+0x4>
   200f4:   000200eb    .word   0x000200eb

为了得到一个好的llvm链接器,你需要构建一个交叉工具,而不仅仅是为你的平台预先构建。最近几个主要的版本在交叉构建时遇到了问题,所以我求助于gcc风格的构建来构建一个特定的架构,这解决了我的很多clang/llvm问题。除了必须为每个版本构建和构建所需的时间。
所以我还没有为llvm构建过armv7-a。我想你会得到同样的结果。注意,我也没有为上面的gcc构建armv 7a。在某种程度上,链接器是做什么的,正如你所看到的,你自己也可以很容易地做到这一点。但是正如评论中所回答的,它生成了一个蹦床,或者我猜人们称之为贴面。
11 vm/叮当声臂7a:

Disassembly of section .text:

000200e4 <thumb_fun-0x6>:
   200e4:   f000 e802   blx 200ec <arm_fun>
   200e8:   e7fe        b.n 200e8 <thumb_fun-0x2>

000200ea <thumb_fun>:
   200ea:   4770        bx  lr

000200ec <arm_fun>:
   200ec:   eaffffff    b   200f0 <__ARMv7ABSLongThunk_thumb_fun>

000200f0 <__ARMv7ABSLongThunk_thumb_fun>:
   200f0:   e300c0eb    movw    ip, #235    ; 0xeb
   200f4:   e340c002    movt    ip, #2
   200f8:   e12fff1c    bx  ip

使用GNU工具-march=armv7-a:

00001000 <thumb_fun-0x6>:
    1000:   f000 e802   blx 1008 <arm_fun>
    1004:   e7fe        b.n 1004 <thumb_fun-0x2>

00001006 <thumb_fun>:
    1006:   4770        bx  lr

00001008 <arm_fun>:
    1008:   ea000000    b   1010 <__thumb_fun_from_arm>
    100c:   00000000    andeq   r0, r0, r0

00001010 <__thumb_fun_from_arm>:
    1010:   e51ff004    ldr pc, [pc, #-4]   ; 1014 <__thumb_fun_from_arm+0x4>
    1014:   00001007    .word   0x00001007

相关问题