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

单重循环,其循环体内不再包含循环结构。下面分循环次数已知和未知两种情况讨论其程序设计法。

一、循环次数已知的单重循环#

对于循环次数已知的情况,通常采用计数控制方法实现循环。

【例 1】 从键盘输入一字符串至 STR1 为首址的字节缓冲区中,试比较该串与字节字符串 STR2 是否相等,若相等,0→BX;否则,0FFFFH→BX。试编其程序。

设计思想:比较两字符串是否相等的首要条件是看这两个字符串的长度是否相等,如不相等,则无再比较的必要,FFFFH→BX,比较结束;如果两串长度相等,则可用串比较指令并带条件的重复前缀,使两串元素逐一比较,如有一对元素不等,则中止重复,FFFFH→BX;如果两串一直到比较完,仍未发现不相等元素,说明两串相等,0→BX。

寄存器分配如下。

根据串操作指令约定的寄存器的要求,设:

SI:源操作数指针,初值指向 SIR1。 DI:目的操作数指针,初值指向 STR2。 CX:两串长度计数器,初值为 n。

另外设:

DX:输入缓冲区指针,初值指向 STR1。 BX:相等否标志寄存器,为 0 表示相等,为 FFFFH 表示不等。程序流程如图 2 所示。

比较两串相等与否的程序流程

图 2 比较两串相等与否的程序流程

程序清单如下:

循环次数已知的单重循环

程序分析:

(1)程序中串比较指令的功能完全可以用前面所学的指令来实现,带重复前缀的串比较也可以用一个循环来代替,故程序结构仍属于循环结构,且为计数控制的循环。

(2)使用串操作指令时,必要的准备工作是:程序中一定要定义附加数据段和事先要设置好方向标志 DF。

(3)使用串操作指令编写的程序简单、精练、方便阅读,程序代码短,编程效率高,占用存储空间小,运行速度快。

思考:

(1)为什么源串的首址为 STR2+2?源串的长度直接置为 80 对否?

(2)当串长度相等后,串比较方向是否可从后面往前面进行?如何修改程序段?

(3)当输入字符串为 xcopy. exe(小写字母)时,BX=?

二、循环次数未知的单重循环#

对于循环次数未知的情况,常用条件来控制循环。

【例 2】 已知若干个非 0 整数 a1,a2,a3,… 存放在以 A 为首址的字存储区中,末尾以 0 作为这组数的结束标志。现要求将其中的负数抹掉,而把留下的正数仍连续地重新存储在以 A 为首址的字存储区中,并把结束标志改为 -1,试编写其程序。

设计思想:这是一个查表程序,数组元素 a1,a2,a3… 存放在内存的一片连续字单元中,组成了一张表。表的长度未知,但以 0 结尾。因此,可用结束标志控制循环。处理的过程为:从表中取一元素,检查其值是否为 0,即检查是否为结束标志。如果是,说明表中元素已处理完毕,则结束循环;否则对元素进行处理,判断其值正负,若为正,则将其送入重新组成的正数表中,然后开始下一次循环,处理下一元素;若为负,则不做任何处理,开始下一次循环。

寄存器分配如下。

SI:原始表取数地址指针,其初值指向 A,每取出一个数之后,值增 2。 BX:新表送数地址指针,其初值指向 A,每送入一个数之后,其值增 2。 AX:用来存放待处理的元素 ai。 注意:SI、BX 均指向同一张表,且初值均指向同一个首址。程序流程如图 3 所示。

例 3 程序流程

图 3 例 3 程序流程

程序清单如下:

循环次数未知的单重循环

程序分析:

(1)由题意可知,欲将旧表中负数抹掉而保存正数,故设置两个指针 SI、BX,在每一次循环后,旧表指针 SI 必增 2,而新表指针 BX 不一定增 2,保证新表指针总是滞后或同步于旧表指针。

(2)程序中欲检查 AX 中内容是否为 0,可采用不同方法来实现,例如 CMP 指令、SUB 指令、ADD 指令等。

(3)程序的最后将结束标志 -1 送新表的字单元中时须加上字类型说明,否则会产生语法错误。

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

3,4,444,600,755,86,775,555,100,200,300,400,432,3276,879,-1

可见 -1 标志之前的数全为正数的集合。

思考:

(1)倘若旧表中无一个正数,则 -1 结束标志最终被送到 A 区的哪一个字单元?

(2)若旧表中无一个负数,则 -1 结束标志最终被送到 A 区的哪一个字单元?

(完)

comments powered by Disqus