用伪指令实现的循环结构
在宏汇编MASM 6.11系统中,还增加了表达循环结构的伪指令,以便更清晰地表达WHILE循环、REPEAT-UNTIL循环。另外,还增加两个辅助循环的伪指令。这 些伪指令的书写格式和含义与高级语言中相应语句的书写格式和含义相一致,所以,这些伪指令是很容易掌握的,也是非常有用的。
循环伪指令的格式和含义如下:
1、WHILE型循环伪指令
.WHILE condition
循环体的指令序列 ;条件"condition”成立时所执行的指令序列
.ENDW
其中:.ENDW与前面的.WHILE相匹配,它标志着其循环体到此结束。
如果条件表达式“condition”在循环开始时,就为“假”(false),那么,该循环体一次也不会被执行。
2、REPEAT型循环伪指令
|
.REPEAT 循环体的指令序列 .UNTIL condition |
.REPEAT 循环体的指令序列 .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 INC NUM1 |
;显示Iteration: 1,2,~,9 |
|||
.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 |