我遇到了Assembly 8086的问题。我不知道如何使用2D数组。当我使用这样的时候
mov ar[cx][dx]
我收到错误,当我想要数组中的SI
和DI
时,它也会返回错误。
答案 0 :(得分:11)
我会在一个以汇编语言提供数组查找语义的CPU中留下深刻印象。或者更确切地说,如果它意味着牺牲了更重要的东西,我会很生气。
在汇编中进行数组查找的一般方法是自己进行计算,将2D数组的两个索引转换为一维数组的单个索引,并调整元素大小。例如(伪代码):
ax = cx * major_dimension
ax = ax + dx
ax = ax * element_size
ax = peek[base+ax]
其中major_dimension
是2D数组的维度之一(您使用的维度完全取决于数据在内存中的布局方式),element_size
是每个元素的大小base
1}}是数组的开头,cx / dx是您用来访问数组的索引。
例如,如果在内存位置a[0-2][0-3]
有一个3乘4(0x0700
)数组且这些是32位整数:
+--------+--------+--------+--------+
0x0700: | a[0,0] | a[0,1] | a[0,2] | a[0,3] |
+--------+--------+--------+--------+
0x0710: | a[1,0] | a[1,1] | a[1,2] | a[1,3] |
+--------+--------+--------+--------+
0x0720: | a[2,0] | a[2,1] | a[2,2] | a[2,3] |
+--------+--------+--------+--------+
要查找数组元素a[n,m]
,您需要计算主索引乘以4加上次要索引,将其缩放到正确的元素大小(4个字节),然后添加基数。要查找元素a[2,1]
addr = base + (n * 4 + m) * 4
= 0x0700 + (2 * 4 + 1) * 4
= 0x0700 + (8 + 1) * 4
= 0x0700 + (9 ) * 4
= 0x0700 + 36
= 0x0700 + 0x24
= 0x0724
那就是你用来查找1D数组的地址。
并且基于以下评论:
ar db 3dup(3dup(0))
mov ar[bx][si],al
会起作用,这是不对的(ar[bx][si]
是与ar[bx+si]
等效的masm特定语法。)
只需在ar
和bx
寄存器中添加si
地址即可。它不缩放bx
或si
注册表以考虑主要维度,它不缩放bx+si
值对于元素大小。所以它只能用于 bytes 的2D数组,其中主要维度是1,我很确定它会成为一维数组: - )
要适用于任何情况,您首先需要将bx
或si
(取决于主要维度使用哪个)乘以主要维度,然后bx
和元素大小si
。
答案 1 :(得分:0)
我对你提出的确切问题并不是很清楚,但是你是否经历了这样的事情(使用基数/索引寻址模式)?
lea bx, array_base
mov si, array_index
mov ax, [bx][si]
答案 2 :(得分:0)
这可以帮到你。
2D数组与1D数组一样存储在内存中,但将其表示为具有行和列。
下面是声明2D数组的代码,该数组以线性方式存储在存储器中。
像这样:
+----------+----------+----------+----------+----------+----------+----------+
index | arr[0][0]| arr[0][1]| arr[0][2]| arr[0][3]| arr[0][4]| arr[1][0]| arr[1][1]|
+----------+----------+----------+----------+----------+----------+----------+
value | 0 | 1 | 2 | 3 | 4 | 10 | 11 |
+----------+----------+----------+----------+----------+----------+----------+
memory address | 1000 | 1004 | 1008 | 1012 | 1016 | 1020 | 1024 |
+----------+----------+----------+----------+----------+----------+----------+
这里每行有4个条目和5列。
现在,如果我想找到值11,arr [1] [1]第1行第1列,那么内存地址将是1024.要首先找到此条目,我必须计算行索引然后列索引。
计算行索引:
因此每行有4个字节,每个4个字节,因此每行将是4 * 5 = 20个字节。条目11在行索引1中,因此1 * 20 = 20,这将在第1行。
计算列索引:
之后,条目11在列索引1中,因此1 * 4 = 4在列索引1处。我们将它乘以4,因为我们已将其声明为4个字节的DWORD。
最后只添加结果(行索引+ col索引)20 + 4 = 24.当我们将其添加到第一个条目的内存地址时,我们将跳转到条目11
即:1000 + 24 = 1024
.data
arr DWORD 0,1,2,3,4;这是具有4行的2D数组的声明,5个cols,每个条目需要4个字节,因为它是一个DWORD
DWORD 10,11,12,13,14 DWORD 20,21,22,23,24 DWORD 30,31,32,33,34
ROWSIZE EQU SIZEOF arr;它是一个命名常量,表示每行有20个字节。在每行中有5个cols表示5个条目,每个条目是4个字节,因此4 * 5 = 20。
.CODE
mov ebx,2 * ROWSIZE;行索引= 2
mov esi,3; col index = 3
mov eax,arr [ebx + esi * 4]; EAX = arr [2] [3],这里当我们调用arr [0]时,它将是条目0,因此条目11将是arr [24]。这意味着从数组的起始内存地址跳过24个字节。