ITEEDU

二、用伪指令实现的分支结构

为了改善汇编语言源程序的结构,减少显式转移语句所带来混乱,在宏汇编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的代码段部分就可写成如下程序段:

…

MOV AL, 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中                                               

例6.9 根据当前计算机的时间和日期,显示上午(AM)或下午(PM),以及所在的季节。

解:

 DATA1 SEGMENT 
 MSG DB "Time: " 
AmPm DB "AM", 13, 10  
 DB "Season: $" 
winter DB "Winter$" 
spring DB "Spring$" 
summer DB "Summer$" 
autumn DB "Autumn$"  
DATA1 ENDS 
CODE1 SEGMENT 
 … 
MOV AH, 2CH ;取当前系统时间 
INT 21H 
.IF CH >= 12  ;下午时间 
  MOV AmPm, 'P'  ;为显示PM作安排 
.ENDIF 
MOV DX, OFFSET MSG 
MOV AH, 09H 
INT 21H ;显示字符串MSG,直到'$'结束 
MOV AH, 2AH 
INT 21H ;取当前系统日期 
.IF (DH == 12) || (DH < 3)  ;判断是否为12月,1月和2月 
  MOV DX, OFFSET winter 
.ELSEIF (DH >= 3) && (DH < 6) ;判断是否为3、4和5月 
  MOV DX, OFFSET spring 
.ELSEIF (DH >= 6) && (DH < 9) ;判断是否为6、7和8月 
  MOV DX, OFFSET summer 
.ELSE ;9、10和11月 
  MOV DX, OFFSET autumn 
.ENDIF 
MOV AH, 09H ;显示季度名称 
INT 21H 
… 
END