2015-09-07 67 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