6.2程序的基本机构2

6.2.3 循环结构

循环结构是一个重要的程序结构,它具有重复执行某段程序的功能。通常,循环结构包括以下四个组成部分:

1、循环初始化部分——初始化循环控制变量、循环体所用到变量;

2、循环体部分——循环结构的主体;

3、循环调整部分——循环控制变量的修改、或循环终止条件的检查;

4、循环控制部分——程序执行的控制转移。

以上四部分可以在程序中用各种不同的形式体现出来,有时也并非清析地表达出来。

一、用循环指令构成循环结构

在编写循环结构的程序片段时,我们可以多种方法来循环结构。如:循环次数是已知的,可用LOOP指令来构造循环;当循环次数是未知或不定的,则可用条件转移或无条件转移来构成循环结构。

例6.11 计算数组score的平均整数,并存入内存字变量Average中,数组以-1为结束标志。

解:

DATA1 SEGMENT

Data DW 90, 95, 54, 65, 36, 78, 66, 0, 99, 50, -1

Average DW 0

DATA1 ENDS

CODE1 SEGMENT

 ASSUME  CS:CODE1, DS:DATA1

 START: MOV AX, DATA1

   MOV DS, AX

   XOR AX, AX

   XOR DX, DX ;用(DX,AX)来保存数组元素之和

   XOR CX, CX ;用CX来保存数组元素个数

   LEA SI, data ;用指针SI来访问整个数组

again: MOV BX, word ptr [SI]

  CMP BX, 0

  JL over

  ADD AX, BX

  ADC DX, 0 ;把当前数组元素之值加到(DX,AX)中

INC CX ;数组元素个数加1

ADD SI, 2

JMP again

over: JCXZ exit;防止零作除数,即数组是空数组

  DIV CX

  MOV Average, AX

exit: MOV AX, 4C00H

   INT 21H

CODE1 ENDS

  END START

二、用伪指令实现的循环结构

在宏汇编MASM 6.11系统中,还增加了表达循环结构的伪指令,以便更清晰地表达WHILE循环、REPEAT-UNTIL循环。另外,还增加两个辅助循环的伪指令。这些伪指令的书写格式和含义与高级语言中相应语句的书写格式和含义相一致,所以,这些伪指令是很容易掌握的,也是非常有用的。

循环伪指令的格式和含义如下:

1、WHILE型循环伪指令

.WHILE condition

  循环体的指令序列    ;条件”condition”成立时所执行的指令序列

.ENDW

其中:.ENDW与前面的.WHILE相匹配,它标志着其循环体到此结束。

如果条件表达式“condition”在循环开始时,就为“假”(false),那么,该循环体一次也不会被执行。

2、REPEAT型循环伪指令

.REPEAT .REPEAT

循环体的指令序列 循环体的指令序列

.UNTIL condition .UNTILCXZ [condition]

REPEAT型循环在执行完循环体后,才判定逻辑表达式condition的值。若该表达式的值为真,则终止该循环,并将执行伪指令.UNTIL[CXZ]后面的指令,否则,将向上跳转到伪指令.REPEAT之后的指令,为继续执行其循环体作准备。

如果.UNTILCXZ后面没有写逻辑表达式,那么,由.REPEAT-.UNTILCXZ所构成的循环与用LOOP指令所过程的循环是一致的,它们都是以“CX=0”为循环终止条件。

如果.UNTILCXZ后面书写了逻辑表达式,那么,该逻辑表达式的形式只能是:“EXP1==EXP2”或“EXP1!=EXP2”。所以,这时由“.REPEAT-.UNTILCXZ condition”所构成的循环就与用LOOPNE/LOOPE指令所过程的循环是一致的,它们都是以“condition || CX=0”为循环终止条件。

和高级语言的REPEAT型的循环一样,.REPEAT-.UNTIL[CXZ]的循环体也会至少被执行一次。

.WHILE-.ENDW和.REPEAT-.UNTIL[CXZ]的循环体内还可再含有循环伪指令,这样就构成了循环结构的嵌套。

汇编程序在生产指令代码时会进行代码优化,以便尽可能得到最优化的指令序列。

3、辅助循环伪指令

(1)终止循环伪指令

.BREAK

.BREAK  .IF condition

该伪指令用来终止包含它的最内层循环。前者是无条件终止循环,后者是仅当逻辑表达式condition为真时,才终止循环。

.WHILE  1 .REPEAT

… …

.BREAK .IF condition .BREAK .IF condition

… …

ENDW .UNTIL 0

对于以上二个循环,如果没有指令来终止循环的话,它们都将进入死循环状态,但如果在该层循环体内,存在伪指令“.BREAK .IF condition”的话,那么,当逻辑表达式condition为真时,该循环就会被终止了。

(2)、循环继续伪指令

.CONTINUE

.CONTINUE .IF condition

该伪指令用于直接跳转到包含它的最内层循环的计算循环条件表达式的代码处。前者是无条件转移到计算循环条件表达式的代码处,后者是仅当条件表达式condition为真时,才进行这样的跳转。

辅助循环伪指令.BREAK和.CONTINUE只能在伪指令.WHILE-.ENDW和.REPEAT-.UNTIL的循环体内使用。 

例6.12 显示9个数字字母'1'~'9',26个大写字母,和显示任意输入的数字字符,并用按“回车”键来结束本程序的运行。

解:

DATA1 SEGMENT

  MSG1 DB 13, 10,  “Iteration: “

  NUM1 DB '1', “$”

  MSG2 DB 13, 10,  “Alphabet: $”

  NUM2 DB 'A', ” $”

  MSG3 DB 13, 10, “Type digits, then press ENTER: $”

DATA1 ENDS

CODE1 SEGMENT

ASSUME  CS:CODE1, DS:DATA1

START: MOV AX, DATA1

  MOV DS, AX

  MOV CX, 9

  MOV AH, 09H

  MOV DX, OFFSET MSG1

  .REPEAT

INT 21H ;显示Iteration: 1,2,~,9

INC  NUM1

.UNTILCXZ

MOV DX, OFFSET MSG2

INT 21H ;显示字符串”Alphabet:”

MOV AH, 09H

MOV DX, OFFSET NUM2

 .REPEAT

 INT 21H ;显示当前字母

 INC  NUM2 ;当前字母向后移

 .UNTIL NUM2 > 'Z';显示整个大写字母表

 MOV AH, 09H

 MOV DX , OFFSET MSG3

 INT 21H

.WHILE  1 ;循环条件为永真的循环

MOV  AH, 07H

    INT 21H ;不带回显地从键盘读一个字符

.BREAK .IF AL == 13 ;如果输入“回车”键,则终止循环

.CONTINUE .IF (AL<'0') || (AL>'9') ;如果字符不是数字字符,则继续循环

MOV  DL, AL

MOV  AH, 02H

INT 21H ;显示所输入的数字字母

.ENDW

MOV AX, 4C00H

INT 21H

CODE1 ENDS

  END START

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...