汇编语言多重循环程序设计

单重循环程序的特点是在循环体内只有顺序程序和分支程序,不包含循环结构。但在实际应用中,循环体内包含有循环结构的情况经常遇到。这种循环体内包含有循环结构的程序叫作多重循环程序。

一、多重循环程序设计

多重循环即循环体内再套有循环。设计多重循环程序时,可以从外层循环到内层循环一层一层地进行。通常在设计外层循环时,仅把内层循环看成一个处理粗框,然后再将该粗框细化,分成置初值、工作、修改和控制四个组成部分。当内层循环设计完之后,用其替换外层循环体中被视为一个处理粗框的对应部分,这样就构成了一个多重循环。对于程序,这种替换是必要的;对于流程图,如果关系复杂,可以不替换,只要把细化的流程图与其对应的处理粗框联系起来即可。

下面举例说明多重循环程序的设计。

【例 3】 已知 m×n 矩阵 A 的元素 aij 按行序存放在以 BUFA 为首址的字节存储区中,aij 为 8位二进制数。试编写程序,求每行元素之和 S1,S2,…,Sn,顺序存入 BUFS 开始的缓冲区中。

设计思想:确定每行元素之和的计算公式为:

多重循环程序设计

多重循环程序设计

S1,S2,…,Sm 的计算过程完全一致,可用循环实现,其流程如图 4 所示。

计算 S1,S2,…,Sm 的程序流程

图 4 计算 S1,S2,…,Sm 的程序流程

图 4 中,计算 Si 是一粗框,处理此框时,i 已确定,变化是以 j 值,求 Si 的过程如下:

多重循环程序设计

其流程如图 5 所示。

计算 Si 的流程

图 5 计算 Si 的流程

图 5 是图 4 第三框细化后的流程图。显然,它包含在图 4 的循环体中。而图 5 自身也是一循环结构,即在图 4 的循环体中出现的循环结构,这就构成了两重循环。用图 5 替换图 4 中的第三框,就是该两重循环程序完整的处理流程图,如图 6 所示。

例 3 程序流程

图 6 例 3 程序流程

至此,算法的处理流程图已给出,但图中的变量 i、j、Si 必须与计算机的存储单元或寄存器联系起来才能编制程序。

寄存器、存储单元分配如下。

  • BX:存放外循环控制变量 i 的值,初值为 1,每循环一次加 1。
  • CX:存放内循环控制变量 j 的值,初值为 1,每循环一次加 1。
  • DX:累加一行元素之和 Si(设 Si 值不超过字范围)。
  • AX:存放 aij(将 aij 扩展为字,以便累加)。
  • 字存储区 BUFS:存放行元素之和 Si。
  • SI:BUFA 区的地址指针,初值指向 BUFA,每当取出一个 aij 之后,其值增 1。
  • DI:BUFS 区的地址指针,初值指向 BUFS,每当存入一个 Si 之后,其值增 2。

程序清单如下:

多重循环程序设计

程序分析:程序中由于通过比较 i 的值是否超过 m 来控制外循环、比较 j 的值是否超过 n 来控制内循环,故多了两次比较,为此影响程序运行速度。如果内外循环都用 CX 进行循环计数,改用循环控制指令 LOOP,程序将更为简洁。下面给出使用这种方法设计的程序清单。

多重循环程序设计

结果分析:在 DEBUG 软件的环境中运行观察到,以 BUFS 为首址的字存储区的内容如下:

以 BUFS 为首址的字存储区的内容

二、多重循环程序设计举例

【例 4】 在以BUF为首址的字节存储区中存放有 n 个无符号数 X1,X2,…,Xn,现需将它们按从小到大的顺序排列在 BUF 存储区中,试编写其程序。

设计思想:

对这个问题的处理可采用逐一比较法,其算法如下:

将第一个存储单元中的数与其后 N-1 个存储单元中的数逐一比较,每次比较之后,总是把小者放入第一个存储单元之中,经过 N-1 次比较之后,N 个数中最小者存入了第一个存储单元之中;接着,将第二个存储单元中的数与其后的 N-2 个存储单元中的数逐一比较,每次比较之后,总是把小者放在第二个存储单元之中,经过 N-2 次比较之后,N 个数中第二个小者存入了第二个存储单元之中……如此重复下去,当最后两个存储单元之中的数比较完之后,从小到大的顺序就实现了。

例如,N=4,4 个数的次序如下:

多重循环程序设计

现要将它们按从小到大的次序重新排列。

4 个数的排序需要比较3遍才能完成。比较的情况如下。

(1)第一遍(比较三次)将第一单元中的 26 与其后的 78、54、17 逐一比较,前两次比较因前者小、后者大,故不交换位置。第三次是将 26 与 17 比较,因后者更小,故两者交换位置。此时,4 个数的次序如下:

多重循环程序设计

(2)第二遍(比较两次)比较的处理过程和第一遍相同,只是比较的次数依次递减。

(3)经过三遍比较,4 个数已排成递增序列。

从上述排序过程可知,对 于N 个数,经过 N-1 遍共 [(n-1)+1](n-1)/2 次比较之后,整个由小到大的次序就排好。若用 i 表示遍数,则第 i 遍是将第 i 个单元中的数与第 i+1、第 i+2……第 N 个单元中的数逐一比较,每次比较之后,总是将小者放入第 i 个单元中。显然,这是一个循环过程,当 i 从 1 到 N-1 循环之后,N 个数的排序就完成了。

由于 N 个数 X1,X2,…,Xn 依次存放在以 BUF 为首址的字节存储区,故 Xi 存放单元的地址为:BUF+i-1(i=1,2,…,n-1,n)。

寄存器分配如下。

  • SI:存放 i 的值,初值为 1,每循环一次之后,其值增 1。
  • DI:存放 j 的值,初值为 i+1,每循环一次之后,其值增 1。
  • AL:用来存放 Xi。

程序流程如图 7 所示。

将 N 个数递增排序的流程

图 7 将 N 个数递增排序的流程

程序清单如下:

多重循环程序设计

程序分析:

程序中的外循环体被重复执行了 N-1 次,即当 i=1,2,…,N-1 时重复执行,i=N 时结束循环。第一次执行外循环体之后,将最小数存入字节单元 BUF 之中;第二次执行外循环体之后,将第二小的数存入字节单元 BUF+1 中;……第 N-1 次执行外循环体之后,将第 N-1 小的数存入字节单元 BUF+N-2 之中,而将最大数存入字节单元 BUF+N-1 之中。此时,存放在以 BUF 为首址的字节存储区中的 N 个 8 位无符号二进制数已排成递增序列。

结果分析:

在 DEBUG 软件的环境中运行,观察到以 BUF 为首址的字节存储区的内容如下:

多重循环程序设计

思考:

(1)若使用 LOOP 指令实现循环控制,程序应如何改动?

(2)若要对 N 个 16 位无符号数进行排序,应如何修改补充程序?

(3)试用其他排序方法编制程序,并比较其优劣。

【例 5】 内存 DATA 开始存放 100 个单字节数据。编写程序统计这些数据内 0 和 1 个数相等的数据个数,将结果存入 NUMB 单元。

完成此例需要一个数据一个数据地检查 0 和 1 是否相等,相等时则计数加 1,直到 100 个数据检查完毕。

多重循环程序设计

请参阅

(完)

comments powered by Disqus