汇编语言8086

问题描述 投票:0回答:4

我的程序集 8086 有问题。我不知道如何使用二维数组。当我这样使用时

mov ar[cx][dx]
我收到一个错误,当我想要将
SI
DI
放入数组中时,它也会返回错误。

assembly x86-16
4个回答
11
投票

如果 CPU 以汇编语言提供数组查找语义,我会印象非常深刻。或者更确切地说,如果这意味着牺牲了更重要的东西,我会很生气。

在汇编中进行数组查找的一般方法是通过自己计算将二维数组的两个索引转换为一维数组的单个索引,并调整元素大小。例如(伪代码):

ax = cx * major_dimension
ax = ax + dx
ax = ax * element_size
ax = peek[base+ax]

其中

major_dimension
是二维数组的维度之一(使用哪个维度完全取决于数据在内存中的布局方式),
element_size
是每个元素的大小,
base
是数组的开头array 和 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 字节),然后添加基数。查找元素
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

这就是您用于查找一维数组的地址。


并且,根据评论:

ar   db   3dup(3dup(0))
     mov  ar[bx][si],al

可以工作,但不太正确(

ar[bx][si]
是masm特定的语法,相当于
ar[bx+si]
)。

所做的只是将

ar
地址与
bx
si
寄存器简单相加。它不会缩放 bx
si
寄存器以考虑主要尺寸,并且不会缩放元素大小的
bx+si
值。因此,它只能按原样用于 bytes 的 2D 数组,其中主要维度为 1,我很确定这会使其成为 1D 数组:-)

要适用于任何情况,您首先需要将 bx

si

(取决于用于主维度的哪个)乘以主维度,然后将

bx
si
乘以元素大小。
    
我不太清楚你要问的确切问题,但你是否在追求类似的东西(使用基址/索引寻址模式)?


0
投票

这可以帮助你。 

0
投票

下面是声明线性存储在内存中的二维数组的代码。

像这样:

+----------+----------+----------+----------+----------+----------+----------+ 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] row 1 col 1 ,那么内存地址将为 1024。要首先找到该条目,我必须计算行索引,然后计算列索引。

计算行索引:

所以每行有 5 个条目,每行 4 个字节,因此每行将有 4*5=20 个字节。条目 11 位于行索引 1 中,因此 1*20 = 20 将位于第 1 行。

计算列索引:

之后条目 11 位于列索引 1 中,因此 1*4= 4 位于列索引 1 处。我们将其乘以 4,因为我们已将其声明为 4 个字节的 DWORD。 最后只需添加结果(行索引 + 列索引)20+4 = 24。当我们将其添加到第一个条目的内存地址时,我们将跳转到条目 11

即:1000+24 = 1024

.数据

arr 双字 0, 1, 2, 3, 4 ;这是 4 行 5 列的 2D 数组的声明,每个条目占用 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 列,意味着 5 个条目,每个条目有 4 个字节,因此 4*5 = 20。

.代码

mov ebx, 2*ROWSIZE;行索引 = 2

mov esi,3;列索引 = 3

mov eax, arr[ebx+esi*4] ; EAX = arr[2][3],这里当我们调用 arr[0] 时,它将是条目 0,因此条目 11 将是 arr[24]。这意味着从数组的起始内存地址开始跳过 24 个字节。

我目前正在开发一个针对8086架构的汇编语言程序。该计划旨在完成以下任务:

0
投票

根据用户的出生月份和卷数模 80 在特定位置显示名字。

在下一行显示姓氏,移动五个位置。指定一个等于用户卷数的十六进制转换的属性值,并考虑对超过 80 的值进行调整。

我在高效编写该程序时遇到了挑战。有人可以提供见解、建议或代码片段来帮助我在 8086 汇编语言框架内实现这些目标吗?

© www.soinside.com 2019 - 2024. All rights reserved.