将 a[1][1] 转换为线性地址取决于您。换句话说,我们必须a[1][1]
弄清楚这距离a
. 我们首先计算一行的大小——在本例中为 2 个整数。因此,(目前在整数中工作)第 0 行的开头位于距 a 的偏移 0 处,第 1 行位于偏移 2 处,并且(如果有更多行)以此类推。然后我们添加该行内的偏移量。最后,我们按单个项目的大小对其进行缩放。
从那里开始,我们有几种可能性。a[1][1]
一个是我们只需要一个固定的位置——无论如何,我们都会得到。另一个是我们真的在看a[i][j]
, where i
andj
恰好是 1 ,但可能是其他大小。
首先,我们可以利用汇编器可以做一些数学运算来为我们计算地址这一事实。
// one row down times 2 ints per row + offset of 1 into last row, all times size of int
movl a + (1 * 2 + 1)*4, eax
在第二种情况下,假设我们有i
inesi
和j
in ebx
。在这种情况下,我们必须自己进行数学运算(抱歉,目前我将使用 Intel 语法——我只是更习惯了):
shl esi, 1 ; i * 2
add esi, ebx ; i * 2 + j
shl esi, 2 ;(i * 2 + j) * 4
mov eax, a[esi]
x86 实际上可以组合一些常见的寻址操作,因此您不必像我上面那样将它们作为单独的指令执行,因此我们可以很容易地将其简化为:
shl esi, 1
mov eax, a[esi][ebx]
最后一点可能需要一些解释——至少对于 MASM(我猜可能还有 gas),汇编器知道,因为你正在加载一个值eax
,所以你正在以 4 字节的数量工作,所以它自动将偏移量缩放 4。