Доступ и изменение массива в сборке Armv8 - PullRequest
0 голосов
/ 21 февраля 2019

Я сейчас изучаю язык ассемблера Armv8 и не совсем понимаю, что здесь происходит.Мы должны предположить, что vec содержит 64-разрядные целые числа, а i - 64-разрядное целое число.Мы также предполагаем, что адрес vec находится в x0, а i находится в x1.

//The C equivalent: vec[i] = vec[i] * 2

lsl x1, x1, 3 // multiply i by 8 because vec of 8 byte ints
add x0, x0, x1 // add offset to base address of array
ldr x2, [x0, 0] // load item from memory
lsl x2, x2, 1 // multiply it by 2.
str x2, [x0, 0] // store it back to memory

Я несколько понимаю инструкцию ldr, поскольку она говорит о необходимости сохранения в регистр x2 значения из x0.Но я не понимаю, как это соответствует значению, которое мы хотим видеть в vec, и что более важно, почему нам нужно использовать логическое смещение влево, а также смещение, используемое в инструкции добавления?

Разбивкаэтой маленькой сборочной программы будет очень признателен!

1 Ответ

0 голосов
/ 21 февраля 2019

Массив хранится в памяти как непрерывные элементы.

Если @v является адресом массива, это будет адрес v [0].Если элементы массива 8 бит, i [1] будет в @ v + 8, i [2] будет в @ v + 16 и т. Д.

-------------------------------------------------------------------------------
|    v[0]    |    v[1]    |    v[2]    |    v[3]    |    ....    |    v[i]    |
-------------------------------------------------------------------------------
^            ^            ^            ^                         ^ 
|            |            |            |                         |            
@v           @v+8         @v+16        @v+24                     @v+i*8

Мы хотим сделать v [i]= v [i] * 2

Предположим,

  • копия i хранится в регистре x1
  • копия @v хранится в x0

Что нам нужно сделать, это

// 1. compute i*8 and put it in x0
lsl x1, x1, 3 // multiply i by 8 because vec of 8 byte ints
// 2. add i*8 to @v in order to compute @v[i] in x0
add x0, x0, x1 // add offset to base address of array
// 2. fetch v[i] === value at @x0 and write it to x2
ldr x2, [x0, 0] // load item from memory
// 3. multiply x2 by 2
lsl x2, x2, 1 // multiply it by 2.
// 4. write back this value at address x0
str x2, [x0, 0] // store it back to memory

Обратите внимание, что первая инструкция умножает x1 на 8, так как i * 8 == i * 2 ^ 3 == i << 3.Первой инструкцией могло бы быть что-то вроде </p>

mul x1, x1, 8 // illegal

Но умножение на немедленное не существует в arm asm, и для этого потребовалось бы две инструкции.

mov x4, 8
mul x1, x1, x4

Инструкция Shift эквивалентна (и дешевле)).

...