用伪指令实现的分支结构
为了改善汇编语言 源程序的结构,减少显式转移语句所带来混乱,在宏汇编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),以及所在的季节。
解:显示解答
6.2.3 循环结构
循环结构是一个重要的程序结构,它具有重复执行某段程序的功能。通常,循环结构包括以下四个组成部分:
1、循环初始化部分——初始化循环控制变量、循环体所用到变量;
2、循环体部分——循环结构的主体;
3、循环调整部分——循环控制变量的修改、或循环终止条件的检查;
4、循环控制部分——程序执行的控制转移。
以上四部分可以在程序中用各种不同的形式体现出来,有时也并非清析地表达出来。常用的循环结构如图6.3所示。
一、用循环指令构成循环结构
在编写循环结构的程序片段时,我们可以多种方法来循环结构。如:循环次数是已知的,可用LOOP指令来构造循环;当循环次数是未知或不定的,则可用条件转移或无条件转移来构成循环结构。
例6.10 分类统计字数组data中正数、负数和零的个数,并分别存入内存字变量Positive、Negative和Zero中,数组元素个数保存在其第一个字中。
解:显示解答
例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 |