Как использовать 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]