Как использовать LDR с логическим сдвигом #2 в ARM-64?

Я пишу несколько программ в сборке ARM. Я хотел написать эквивалент этого:

int array_test(int index)
{
    ...
    arr[0] = 3;
    arr[1] = 9;
    arr[2] = 6;
    return arr[index];
}

где я хочу установить значения массива для индекса 0-2 и вернуть значение массива по данному индексу.

В моей программе я использую

х4 = индекс; SP, SP # 4, SP # 8 = arr [0], arr [1], arr [2]; х0 = возвращаемое значение

Чтобы получить элемент массива, заданный индексом, я хочу умножить индекс на 4 (для размера int) и добавить в SP. Тем не менее, когда я использую

LDR x0, [SP, x4, LSL#2]     // Load to x0, (arr[index]) for return;

Но я получаю эту ошибку с aarch64-linux-android-gcc:

error: expected 'lsl' or 'sxtx' with optional shift of #0 or #3

Тем не менее, я могу получить то же самое с LSL и LDR:

LSL x4, x4, #2      // multiply index by 4 for 32-bit int
LDR x0, [SP, x4]    // Load to x0, (arr[index]) for return;

Почему я не могу использовать LDR с LSL # 2? Только #0 или #3 кажутся действительными.

Спасибо за помощь!

1 ответ

Решение

Вы использовали инструкцию LDR с 64-битным регистром назначения вместо 32-битного.

64-битный вариант загружает восемь байтов в регистр назначения Xn и допускает сдвиг индекса на #0 или # 3

32-битный вариант загружает четыре байта в регистр назначения Wn и допускает сдвиг индекса на #0 или # 2. Регистр Wn расширен до нуля, чтобы зарегистрировать Xn

Вы должны использовать LDR w0, [SP, x4, LSL#2]

Другие вопросы по тегам