在 Armv8 程序集中访问和修改数组
Accessing and modifying an array in Armv8 Assembly
我目前正在研究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指令中使用的偏移量?
非常感谢分解这个小型汇编程序!
数组在内存中存储为连续元素。
如果@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<<3。第一条指令可能是这样的
mul x1, x1, 8 // illegal
但是 arm asm 中不存在立即数乘法,它需要两条指令。
mov x4, 8
mul x1, x1, x4
移位指令是等效的(并且更便宜)。
我目前正在研究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指令中使用的偏移量?
非常感谢分解这个小型汇编程序!
数组在内存中存储为连续元素。
如果@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<<3。第一条指令可能是这样的
mul x1, x1, 8 // illegal
但是 arm asm 中不存在立即数乘法,它需要两条指令。
mov x4, 8
mul x1, x1, x4
移位指令是等效的(并且更便宜)。