2015-09-07 2 views
0

Мне интересно, как реализовать оператор «switch» на ассемблере aarch64. На arm32 платформах я использовал что-то вродереализация коммутатора; рука; ассемблер; aarch64; arm64

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

Но с 64-битной версии есть много ограничений на «ПК» регистр использования, такая реализация не работает больше.

Кажется, что самый простой способ заключается в использовании пары сравнения и отраслевых операции, как

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

Но иногда бывает до десятков случаев, и это приведет к значительной задержке до достижения последних «дел ».

Не могли бы вы поделиться своими идеями о том, как быстро включить коммутатор на aarch64.

Спасибо :)

+0

адр/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

, когда я пытаюсь выполнить этот код, я получил «НЕ МОЖЕТ ЛИСТИРОВАТЬ ИСПОЛНЕНИЕ: текстовые перестановки (DT_TEXTREL), найденные в 64-битном файле ELF». Компиляция и связывание работают нормально ... objdump показывает этот код: «adr \t x4, 26ae0; ldr \t x4, [x4]; br \t x4; ...;« Да, просто «...» вместо фактические адреса. Любые идеи почему? – user3124812

+0

Да, используется независимый код позиции, он должен быть на Android 5. Спасибо Ross – user3124812