MASM 6.11系统中 用伪指令实现的分支结构

转载自: http://hi.baidu.com/younthu/blog/item/75b8946d0e28bdff4216944a.html

 

用伪指令实现的分支结构

为了改善汇编语言源程序的结构,减少显式转移语句所带来混乱,在宏汇编MASM 6.11系统中,增加了表达分支结构的伪指令。该伪指令的书写格式与高级语言的书写方式相类似,汇编程序在汇编时会自动增加转移指令和相应的标号。理解并掌握该知识,对将来学习《编译原理》课程也有一定的帮助。

分支伪指令的具体格式如下:

格式1:

.IF condition    ;以英文“句号”开头
  指令序列     ;条件"condition"成立时所执行的指令序列
.ENDIF

格式2:

.IF condition
  指令序列1
.ELSE
  指令序列2    ;条件"condition"不成立时所执行的指令序列
.ENDIF

格式3:

.IF condition1
  指令序列1
.ELSEIF condition2
  指令序列2    ;条件"condition2"成立时所执行的指令序列
.ENDIF

其中:条件表达式“condition”的书写方式与C语言中条件表达式的书写方式相似,也可用括号来组成复杂的条件表达式。

条件表达式中可用的操作符有:==(等于)、!=(不等)、>(大于)、>=(大于等于)、<(小于)、<=(小于等于)、&(位操作与)、!(逻辑非)、&&(逻辑与)、||(逻辑或)等。

若在条件表达式中检测标志位的信息,则可以使用的符号名有:CARRY?(相当于CF==1)、OVERFLOW?(OF==1)、PARITY?(PF==1)、SIGN?(SF==1)、ZERO?(ZF==1)等。例如:

.IF CARRY? && AX != BX    ;检测CF==1且AX!=BX是否成立
  ;汇编语言指令序列
.ENDIF

在指令序列中,还可再含有其它的.IF伪指令,即:允许嵌套。伪指令.ELSEIF引导出另一个二叉分支,但它不能作伪指令块的第一个伪指令。

汇编程序在对“条件表达式”进行代码转换时将进行代码优化处理,以便尽可能生成最好的指令代码。如:

.IF ax == 0

汇编程序会把它转换为指令“OR ax, ax”,而不是“CMP ax, 0”,因为前者比后者更好,而不是简单直接地转换为后者。

如果用伪指令来书写分支结构,那么,例6.5的代码段部分就可写成如下程序段:

 
MOVAL, CHAR1
.IF AL>='a' && AL<='z';语句象C语言语句吗?
  SUB CHAR1, 20H
.ENDIF
  

也可把例6.6的代码段部分就可写成如下程序段:

 
MOV   AX, X
.IF AX < 0
  ADD AX, 10;计算第一种情况的结果
.ELSEIF AX <= 10
  MOV BX, 30D
  IMUL BX
;计算第二种情况的结果
.ELSE
  SUB AX, 9;计算第三种情况的结果
.ENDIF
MOV Y, AX
;把计算结果保存到变量Y中

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

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个大写字母,和显示任意输入的数字字符,并用按“回车”键来结束本程序的运行。

解:

 DATA1SEGMENT
MSG1DB 13, 10, "Iteration: "
NUM1DB '1', "$"
MSG2DB 13, 10, "Alphabet: $"
NUM2DB 'A', " $"
MSG3DB 13, 10, "Type digits, then press ENTER: $"
DATA1ENDS
CODE1SEGMENT
ASSUME CS:CODE1, DS:DATA1
START:MOVAX, DATA1
MOVDS, AX
MOVCX, 9
MOVAH, 09H
MOVDX, OFFSET MSG1
.REPEAT
 INT 21H
 INC NUM1
;显示Iteration: 1,2,~,9
.UNTILCXZ
MOVDX, OFFSET MSG2
INT21H;显示字符串"Alphabet:"
MOVAH, 09H
MOVDX, OFFSET NUM2
.REPEAT
 INT 21H
 INC NUM2
;显示当前字母
;当前字母向后移
.UNTIL NUM2 > 'Z';显示整个大写字母表
MOVAH, 09H
MOVDX, OFFSET MSG3
INT21H
.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
MOVAX, 4C00H
INT21H
CODE1ENDS
ENDSTART

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值