x86 - 用于访问数组中元素的寻址模式

时间:2012-08-12 04:59:58

标签: arrays assembly x86 addressing-mode

我正在尝试学习汇编语言。有人可以解释和/或举例说明如何使用寻址模式访问以下每种数组类型中的元素吗?

  1. DWORD

  2. 的数组
  3. 结构数组,其中每个结构包含两个DWORD s

  4. 数组数组,其中每个数组都有10个DWORD s

2 个答案:

答案 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语法。

  1. 假设ebx是基址寄存器,esi是元素的索引寄存器。标准32位寄存器(eaxebxecxedxebpesiedi)有效对于此处使用的寻址模式。 esp可以用作基址寄存器,但不能用作索引寄存器。索引寄存器的值可以选择使用2,4或8进行缩放。在此示例中,我们可以使用缩放因子4作为双字阵列(在386个合法缩放因子中为1,2,4和8)。

    将数组中的值读入eaxmov eax, [ebx+4*esi]eax的值存储到数组中:mov [ebx+4*esi], eax

  2. 让我们保持ebx作为基地址。对于结构数组,我们可以使用esi的缩放因子8,其中每个结构由2个双字组成。

    将第一个双字的值读入eaxmov eax, [ebx+8*esi]eax的值存储到第一个词:mov [ebx+8*esi], eax

    将第二个双字的值读入eaxmov eax, [ebx+8*esi+4]eax的值存储到第二个dword:mov [ebx+8*esi+4], eax

    如果索引不能被硬编码,您只需将{4}添加到ebx(或用于存储基址的任何寄存器)。如果您有硬编码的基地址,那么您可以使用例如。 esi来解决结构问题,例如。 ebx来解决您想要的双关语。请注意,在386+中,您无法在间接寻址中扩展多个寄存器(索引寄存器)。

  3. 我们仍然假设您事先并不知道阵列的基地址,并且您会在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的值读取到eaxmov eax,[edi+4*edx]

    eax的值存储到dword:mov [edi+4*edx],eax