综合例题
现在,讲解一个稍微大一点的题目,来看一下,究竟如何从题目一步一步写出汇编语言程序的。
例4.9:
判断一个放在YEAR变量中的年份是否是闰年。
解决步骤:
1) 用人的思维来分析题目要求,用文字描述出来:
遇到一个题目时首先考虑解决这个问题人需要怎么办,并将想法用自然语言描述出来,注意用词尽量使用
“首先…然后…再后…最后…”;
“如果…那么…否则…”;
“依次类推(或依次执行)”
等连词,这是因为这些词汇可以很容易地在流程图中用结构表达出来。
这个问题解决起来很简单:“首先,得到YEAR的值;然后判断该值能否被4整除;如果不能整除,那么是平年,否则判断能否被100整除,如果不能整除,那么是闰年,否则判断能否被400整除,如果能整除,那么是闰年,否则是平年”
2) 根据已经写出的文字描述画出粗略的流程图:
根据文字描述,可以一一对应的画出流程图,具体对应关系是:
“首先”句画成顺序结构;“首先”、“然后”、“再后”、“最后”等词汇就是流程图中的先后顺序,其中“…”表示流程中每一步具体执行的内容,
“如果”句转化成分枝结构流程图;其中“如果”后的内容为分支结构的分支条件,而“那么”后内容是条件为真时执行的内容,“否则”后面是条件不成立时执行的内容,“如果”转换成“◇”菱形框架表示,“那么”、“否则”对应相应的连线,注意根据条件分别标出“Y”、“N”。
循环N次
Y
N
(a) (b)
图4.1
“依次类推(或依次执行)”对应循环结构;注意“次”的概念,如果是循环次数已经确定,则在循环连线上标示出“循环N次”(见图4.1-a),如果是按照某条件成立与否,则参考“如果”句画出流程图(见图4.1-b)。依次执行的内容为循环体的内容。
上面“判断是否是闰年”例题的流程图也可以按照这种方式画出(见图4.2)
3)将粗略的流程图转化成具有汇编语言特点的的流程图:
因为汇编语言中没有结构化语句,因此,流程图中的结构化框架需用汇编语言的无条件跳转指令、条件跳转指令,循环指令等来表达。为了更好的与汇编语言的指令对应,将前面已经画好的流程图进行一些改造,这里主要是涉及到分支的部分,具体改造形式如图4.3。
Y N
N Y
Y N
图4.2
改写成
图4.3
根据这种方法,可以将图4.2的流程改画成图示4.4:
4)将流程图进一步细化:
经过前面步骤所得到的流程图,还不能与汇编语言指令对应,应该结合汇编语言进一步细化,直到流程图中每模块只对应一条或简单的几条指令为止。
例如“判断是否是闰年”题目中“能否整除4”这一步骤,就需要细化成:
①、 将YEAR中得到的值送到积存器AX中
②、 将除数4送到BL(或其它8位积存器中)
③、 用无符号除法指令DIV进行除法运算
④、 余数(在AH中)是否为0
等几个具体步骤
5)根据细化过的编程图写出代码段:
将流程图中每一步转化为对应的汇编语言指令。
此外,尤其注意流程图中连线有一部分也必须对应汇编语言指令,这里主要是指形式上“绕弯”比较大的箭头箭头连线。
①
Y Y N
N Y
②
Y N
图4.4
如果是带有Y,N的分支结构的箭头连线,则先将“绕弯”大的箭头连线用条件跳转指令表达;然后,再写距离近的所执行的内容。如果箭头连线上没有任何标志,则用无条件跳转指令表达,这类无条件跳转指令,用来体现模块化结构体的范围的。
例如:图4.4中的①、②处应该写成:
…
① DIV BL ;YEAR中的值已经存放在AX中,BL存放的为除数4
CMP AH,0
JNZ A1 ;ZF为“假”,表示不能整除
… ;判断能否整除100
…
… ;是闰年
② JMP EXIT
… ;能否整除400
…
A1:… ;是平年
EXIT:… ;结束
6)完善程序:
这里主要是完善汇编语言程序的语法结构。主要内容是在前面的基础上再加上变量定义,段定义,段说明等等,使程序段成为完整的程序。
;…………源程序…………
;…………数据段…………
DATA SEGMENT;数据段定义
YEAR DW xxxx ;YEAR中存放准备判断的年份
YN DB ? ;YN存放结果,1表示闰年,0表示平年
DATA ENDS
;…………代码段…………
CODE SEGMENT
ASSUME CS:CODE,DS:DATA;段说明
START:MOV AX,DATA;数据段积存器DS赋值
MOV DS,AX
;
MOV AX,YEAR;得到YEAR的值
MOV BL,4 ;除以4
DIV BL
CMP AH,0 ;余数是否为0
JNZ A1 ;余数不为0,即不能整除,则跳转到A1处
MOV AX,YEAR;因为上面的除法运算AX的内容已经改
;所以AX需要重新赋值
MOV BL,100
DIV BL
CMP AH,0
JZ A2
MOV YN,1
JMP EXIT
A2:MOV AX,YEAR ;除以400
MOV DX,0 ;因为除数是16位,所以被除数应为32位,
;分别存放在DX:AX
MOV BX,400
DIV BX
CMP DX,0
JNZ A1
MOV YN,1
JMP EXIT
A1:MOV YN,0
;
EXIT:HLT
CODE ENDS
END START