我正在尝试学习汇编语言。有人可以解释和/或举例说明如何使用寻址模式访问以下每种数组类型中的元素吗?
DWORD
结构数组,其中每个结构包含两个DWORD
s
数组数组,其中每个数组都有10个DWORD
s
答案 0 :(得分:2)
逻辑是微不足道的。
一维数组的 i -th元素的地址只是数组的地址(或第0个元素)加上 i * 元素大小。
如果您有一个二维数组,您可以将其视为一维数组的一维数组,并将其简化为我刚刚描述的已经熟悉的情况: i的地址 i * 子阵列大小。在 i -th子阵列中,我们已经知道如何计算 j -th元素地址。
因此,二维数组的(i,j) -th元素的地址只是数组的地址加上 i * 子数组size + j * 元素大小 OR,等效地,数组的地址加上( i * 元素的数量在行 + j )* 元素大小。
你应该能够弄清楚如何用汇编语言来做这件事。
答案 1 :(得分:2)
您没有具体提到您要定位的处理器,但是在386+中这可行。我没有MASM,但MASM使用Intel语法。
假设ebx
是基址寄存器,esi
是元素的索引寄存器。标准32位寄存器(eax
,ebx
,ecx
,edx
,ebp
,esi
,edi
)有效对于此处使用的寻址模式。 esp
可以用作基址寄存器,但不能用作索引寄存器。索引寄存器的值可以选择使用2,4或8进行缩放。在此示例中,我们可以使用缩放因子4作为双字阵列(在386个合法缩放因子中为1,2,4和8)。
将数组中的值读入eax
:mov eax, [ebx+4*esi]
将eax
的值存储到数组中:mov [ebx+4*esi], eax
让我们保持ebx
作为基地址。对于结构数组,我们可以使用esi
的缩放因子8,其中每个结构由2个双字组成。
将第一个双字的值读入eax
:mov eax, [ebx+8*esi]
将eax
的值存储到第一个词:mov [ebx+8*esi], eax
将第二个双字的值读入eax
:mov eax, [ebx+8*esi+4]
将eax
的值存储到第二个dword:mov [ebx+8*esi+4], eax
如果索引不能被硬编码,您只需将{4}添加到ebx
(或用于存储基址的任何寄存器)。如果您有硬编码的基地址,那么您可以使用例如。 esi
来解决结构问题,例如。 ebx
来解决您想要的双关语。请注意,在386+中,您无法在间接寻址中扩展多个寄存器(索引寄存器)。
我们仍然假设您事先并不知道阵列的基地址,并且您会在ebx
esi
中找到它拥有结构的索引,在edx
中你有dword的索引。
要获取结构的地址,您可以使用lea
乘法优化(10 = 8 + 2):
修改:修正:lea esi,[4*esi]
(双字是4个字节)
lea edi,[ebx+8*esi]
lea edi,[edi+2*esi]
现在您拥有edi
中结构的地址。您只需要添加dword的索引(在此示例中存储在edx
中)乘以4(因为每个双字是4个字节)。
要将dword的值读取到eax
:mov eax,[edi+4*edx]
。
将eax
的值存储到dword:mov [edi+4*edx],eax
。