实验二 分支、循环程序设计
一、实验目的
1. 开始独立进行汇编语言程序设计; 2. 掌握基本分支,循环程序设计; 3. 掌握最简单的 DOS 功能调用。
二、实验内容
1. 安排一个数据区,内存有若干个正数,负数和零。每类数的个数都不超过 9。 2. 编写一个程序统计数据区中正数,负数和零的个数。 3. 将统计结果在屏幕上显示。
4. (选作题)统计出正奇数、正偶数,负奇数、负偶数以及零的个数。
三、预习思考
1. 十进制数 0 ~ 9 所对应的 ASCII 码是什么? 如何将十进制数 0 ~ 9 在屏幕
上显示出来?
? 0~9对应的ASCII码分别为30H~39H。
? 若将数字0~9显示在屏幕上,只需要用二进制数0~9分别加上30H得到相应的
ASCII码,再通过DOS功能调用AH=02H显示相应的数字。
2. 如何检验一个数为正,为负或为零? 你能举出多少种不同的方法? ? 使用CMP命令,将该带符号数数与0比较,然后进行判断。如果大于0,则使用
JG命令进行跳转;如果等于0,则使用JE命令进行跳转;如果小于0,则使用JL命令进行跳转,通过观察跳转后执行不同程序的结果来判断进行了哪个跳转,从而判断大小。
? 先将该数和0相比观察结果是否相等,可利用JE命令;然后使用AND命令将该数
(假设为8位)和10000000相与,结果存在该数中,取出符号位进行判断,可区分正负。除了AND命令,也可用TEST命令,然后使用JNZ命令进行跳转。 ? 先将该数和0相比观察结果是否相等,可利用JE命令;然后使用SHL逻辑左移命
令,左移一位后将符号位移入标志寄存器CF中,检查CF的值即可。
四、流程图
开始定义数据段数组中的多个变量CL=0?否偏移地址SI+1数组长度CL-1是取出数>=0?否是取出数>0?是否负数个数加1正数个数加1零的个数加1和1与运算,结果加入到负奇数中和1与运算,结果加入到正奇数中统计正数、负数、零、正奇数、负奇数的个数计算正偶数、负偶数的个数并显示结束
五、源代码
DATA SEGMENT ;数据段 ARRAY DB 7,-4,3,-2,0,-5,1,9,8,0,5,-4,-3,0 ;14个数据 LENG EQU $-ARRAY ;数组长度 POSI DB ? ;正数个数 NEGT DB ? ;负数个数 ZERO DB ? ;零的个数 POSIODD DB ? ;正奇数 POSIEVEV DB ? ;正偶数 NEGTODD DB ? ;负奇数 NEGTEVEV DB ? ;负偶数 POSICHAR DB 'Positive: $' ;打印提示字符Positive NEGTCHAR DB 'Negtive: $' ;打印提示字符Negtive ZEROCHAR DB 'Zero: $' ;打印提示字符Zero ODDCHAR DB ' Odd: $' ;加入空格且打印提示字符Odd(奇数) EVENCHAR DB ' Even: $' ;加入空格且打印提示字符Even(偶数) CR DB 0DH,0AH,'$' ;回车和换行的ASCII码 DATA ENDS ;-------------------------------------------------------- CODE SEGMENT ;代码段 ASSUME CS:CODE,DS:DATA ;-------------------------------------------------------- START: MOV AX,DATA MOV DS,AX ;给数据段段基址赋值 MOV SI,OFFSET ARRAY-1 ;取数组的偏移地址-1,采用寄存器间接寻址 MOV CL,LENG ;将数组长度赋予CL MOV AL,0 ;AL数值为0 CMP CL,0 ;循环控制条件:数组长度减为零 JE CALC ;如果数组长度为零则跳出 INC SI ;SI为数组ARRAY中第一个数字的偏移地址,之后的每个循环依次加1 DEC CL ;数组长度减1 MOV BL,[SI] ;采用寄存器间接寻址 CMP BL,AL ;和零比较 JG ISPOSI ;带符号数,是正数跳转 JE ISZERO ;是零跳转 JL ISNEGT ;带符号数,是负数跳转 LOOP1: ;-------------------------------------------------------- ISPOSI: INC POSI ;正数的个数加1 AND BX,1 ADD POSIODD,BL ;和1进行与运算,如果低位为0即偶数,则加0;如果低 位为1即奇数,则加1。所以正奇数加1 JMP LOOP1 ;继续循环 ISZERO: INC ZERO ;0的个数加1 JMP LOOP1 ;继续循环 ISNEGT: INC NEGT ;负数个数加1 AND BX,1 ADD NEGTODD,BL ;同理,和1进行与运算之后结果加到负奇数中 JMP LOOP1 ;继续循环 ;-------------------------------------------------------- CALC: MOV AH,POSI MOV AL,POSIODD SUB AH,AL ;用正数的个数减去正奇数的个数,结果为正偶数的个数 MOV POSIEVEV,AH ;正偶数 MOV AH,NEGT MOV AL,NEGTODD SUB AH,AL ;同理,结果为负偶数的个数 MOV NEGTEVEV,AH ;负偶数 ;-------------------------------------------------------- PRINT: ;打印正数提示符、正数、正奇数、正偶数 MOV AH,09H ;显示字符串 MOV DX,OFFSET POSICHAR ;打印提示字符Positive INT 21H ;DOS功能调用 MOV AH,02H ;显示单个字符 MOV DL,POSI ;正数个数写到显示字符串的入口参数 ADD DL,30H ;正数个数的ASCII码 INT 21H ;DOS功能调用 MOV AH,09H ;后面的显示原理均相同,先显示提示字符串,然后显示单个数字 MOV DX,OFFSET ODDCHAR INT 21H MOV AH,02H MOV DL,POSIODD ADD DL,30H INT 21H MOV AH,09H MOV DX,OFFSET EVENCHAR INT 21H MOV AH,02H MOV DL,POSIEVEV ADD DL,30H INT 21H MOV DX,OFFSET CR MOV AH,09H INT 21H ;-------------------------------------------------------- ;同理,打印负数提示符、负数、负奇数、负偶数 MOV AH,09H MOV DX,OFFSET NEGTCHAR INT 21H MOV AH,02H MOV DL,NEGT ADD DL,30H INT 21H MOV AH,09H MOV DX,OFFSET ODDCHAR INT 21H MOV AH,02H MOV DL,NEGTODD ADD DL,30H INT 21H MOV AH,09H MOV DX,OFFSET EVENCHAR INT 21H MOV AH,02H MOV DL,NEGTEVEV ADD DL,30H