【问题标题】:Accessing and modifying an array in Armv8 Assembly在 Armv8 Assembly 中访问和修改数组
【发布时间】:2019-02-21 02:32:18
【问题描述】:

我目前正在研究 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 指令,因为它是说将来自 x0 的值存储到寄存器 x2 中。但是我不明白这与我们想要在 vec 中的值如何对应,更重要的是为什么我们需要使用逻辑左移以及 add 指令中使用的偏移量?

非常感谢分解这个小型汇编程序!

【问题讨论】:

  • lsl x1, x1, 3 与 x1 乘以 8 相同。但是,lsl 需要 1 个周期,而 mult 需要 2 个(在 A76 上)。
  • AArch64 不能进行缩放索引内存寻址吗?是的,GCC使用ldr x2, [x0, x1, lsl 3],clang选择单独缩放索引,然后使用双寄存器寻址模式。 godbolt.org/z/WMr48K。所以这个例子只是出于教学目的手动进行地址计算。

标签: arrays assembly arm64 armv8


【解决方案1】:

数组作为连续元素存储在内存中。

如果@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 的副本存储在 reg 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,即 i8 == i2^3 == i

mul x1, x1, 8 // illegal

但在 arm asm 中不存在立即数乘法,它需要两条指令。

mov x4, 8
mul x1, x1, x4

移位指令是等效的(而且更便宜)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-15
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多