2015-09-07 69 views
0

我对在aarch64汇编器上实现'switch'操作符的方式感兴趣。 在ARM32平台,我用类似切换执行;臂;汇编; aarch64; arm64

ldr   pc,   [pc, ta, LSL#2] 
    nop           // alignment 
    .int  .L.case1 
    .int  .L.case2 
    ... 
    .int  .L.caseN 

但由于64位版本有“PC”有很多限制的寄存器使用,这样的实现不工作了。

看来,最简单的方法是使用对比较和分支操作,如

cmp ta, #1 
b.eq .L.case1 
cmp ta, #2 
b.eq .L.case2 
... 

但有时也有长达十几例,它到达最后一个“的情况下才将导致显著延迟”。

请您分享一下您的想法如何在aarch64上实现快速切换。

谢谢:)

+0

ADR/ADRP可用于“PC-相对地址计算“。 – auselen

回答

1

我没有一个64位的ARM汇编程序来测试这一点,但我相信你会做类似下面来实现跳转表:

adr x0, jmp_table 
    ldr x0, [x0, x1, LSL#3] 
    br x0 

jmp_table: 
    .quad .L.case1 
    .quad .L.case2 
    .quad .L.case3 

的第一条指令ADR将标签的地址加载到寄存器中。最后一条指令BR跳转到存储在寄存器中的地址。

如果您要创建一个共享库或位置无关可执行文件,你可以尝试像下面的内容:

adr x0, jmp_table 
    add x0, x0, x1, LSL#2 
    br x0 

jmp_table: 
    b .L.case1 
    b .L.case2 
    b .L.case3 

备用PIC例如

adr x0, jmp_table 
    ldr w1, [x0, x1, LSL#2] 
    add x0, x0, x1 
    br x0 

jmp_table: 
    .int .L.case1 - jmp_table 
    .int .L.case2 - jmp_table 
    .int .L.case3 - jmp_table 
+0

当我尝试执行此代码时,我得到了“CAN NOT LINK EXECUTABLE:在64位ELF文件中找到的文本重定位(DT_TEXTREL)”。编译和链接工作正常... objdump显示此代码,如:“adr \t x4,26ae0; ldr \t x4,[x4]; br \t x4; ...;”是,只是“...”而不是实际地址。任何想法为什么? – user3124812

+0

是的,位置独立的代码被使用,它必须在Android 5.谢谢罗斯 – user3124812