统计数
1. 需求说明
1.1设计要求:
进一步理解和掌握较复杂程序的设计方法,掌握子程序结构的设计和友好用户界面的设计。
具体的设计任务及要求:
1. 输入若干个十进制字数据;
2. 统计其中最高6位全为1的数的个数;
3. 输出满足要求的数的个数和具体的数
4. 程序采用子程序结构或宏指令,结构清晰;
5.友好清晰的用户界面,能识别输入错误并控制错误的修改。
1.2设计说明
本程序首先需要输入一个0到9的数字并将其保存到cx中,用来确定需要输入数字的数量,首先,每次输入一个数字后就将它转化为10进制数字保存到buf中,将所有需要输入的数字输入完后再依次对buf中的数字进行判断,我的判断方法是利用循环将数字左移一位,判断cf的值来确定是否符合要求,最后将符合要求的数和个数输出,在进行判断是否再一次执行程序
1.3功能简述
程序可以首先输入一个小于10的数字n,确定要输入多少个数字,然后每输入一个数字检查是否超过1个字的存储范围;若输入有误则提示错误,并提示重新输入,若输入正确个字数据后,系统将显示出所有满足要求的数的个数和数。
然后提示是否继续,若用户输入y或Y,则系统回到最开始的状态,若输入n或N,则退出系统,若为其他则提示错误,并重新输入。
2. 设计说明(简要的分析与概要设计)
2.1简要分析
2.1.1原理说明
本程序首先需要输入一个0到9的数字并将其保存到cx中,用来确定需要输入数字的数量,首先,每次输入一个数字后就将它转化为10进制数字保存到buf中,将所有需要输入的数字输入完后再依次对buf中的数字进行判断,我的判断方法是利用循环将数字左移一位,判断cf的值来确定是否符合要求,最后将符合要求的数和个数输出,在进行判断是否再一次执行程序
2.1.2程序流程图
(主要操作流程图)
(将字符串转化成10进制)
(将10进制数据输出)
2.2 数据段设计
data segment
many db 'How many numbers you want to input(0~9)? $'
tip db 'Please input a number(0~65535): $'
next db 'Do you want to go on Y/N ?$'
nice db 'The numbers you want are: $'
fail db 'There is something wrong in your input! $'
toll db ' numbers you want.$'
nextword db ?
buf dw 10 dup(0);设置buf区域保存转换后的数字
string db 10;设置字符串输入区域
db 0
db 10 dup(0)
claf db 0dh,0ah,'$'
data ends
分析:
前六条语句主要用于进行提示性语句的输出
Nextword 变量用于保存所需输入字的个数
Buf 用于保存将字符串转化成10进制的数字
String 用于设计10号中断的字符串输入
Claf 用于换行的操作
3.主要子程序(或宏指令)设计与描述
1)clafp子程序
;----------
;子程序功能:换行
;使用到的寄存器:
;dx:保存偏移地址
;ah:调用中断
;------------
clafp proc
lea dx,claf
mov ah,9
int 21h
ret
clafp endp
;------------
2)cin子程序
;------------
;子程序功能:输入字符串
;使用到的寄存器
;cx:记录输入字的数量
;ah:调用中断
;dx:保存偏移地址
;------------------
cin proc
dec cx
lea dx,tip;输出提示性字符串
mov ah,9
int 21h
call clafp
mov ah,10
lea dx,string;输入字符串
int 21h
push cx
call tonum;将字符串转化成10进制数
cmp al,1;判断是否满足要求
jz L4
pop cx
inc cx
push cx
L4: pop cx
call clafp
ret
cin endp
;-----------------------
3)tonum子程序
;子程序功能:将字符串转化成10进制数
;用到的寄存器:si源字符串
;di指向目标地址
;cx保存字符串长度
;ax保存转换的字符
;bl保存每一位的字符
;----------------------------
tonum proc
mov si,2
mov cl,string+1;判断字数是否超出范围
cmp cl,5
ja err
mov ch,0
xor ax,ax
L2:
mov bl,string[si]
inc si
cmp bl,'9';判断每一位是否符合要求
ja err
cmp bl,'0'
jb err
sub bl,'0'
mov bh,0
mov dx,10;乘以10在加个位数
mul dx
jc err
add ax,bx
jc err
loop L2
mov buf[di],ax
add di,2
mov al,1
ret
err:;如果错误则输出错误信息
lea dx,fail
mov ah,9
int 21h
lea dx,claf
int 21h
mov al,0
ret
tonum endp
;-----------------------
4)print子程序
;子程序功能:将字型数字输出
;用到的寄存器:
;si源字,在子程序前应该赋值
;ax,dx用于除法
;bx用作除数
;---------------------
print proc
mov ax,buf[di]
mov dx,0
mov bx,10000;将10进制的每一位输出
div bx;这里时间紧不做化简
push dx
mov dl,36h
mov ah,2
int 21h
pop ax
mov dx,0
mov bx,1000
div bx
push dx
mov dl,al
mov ah,2
add dl,30h
int 21h
pop ax
mov dx,0
mov bx,100
div bx
push dx
mov dl,al
mov ah,2
add dl,30h
int 21h
pop ax
mov dx,0
mov bx,10
div bx
push dx
mov dl,al
mov ah,2
add dl,30h
int 21h
pop ax
mov dx,0
mov bx,1
div bx
mov dl,al
mov ah,2
add dl,30h
int 21h
lea dx,claf
mov ah,9
int 21h
ret
print endp
;---------------
5)judge子程序
;子程序功能:判断十进制数是否满足前6位为1
;用到的寄存器
;bx:保存10进制数
;cx:保存1的个数
;返回参数:若满足要求al=1,否则al=0
;--------------------
judge proc
mov bx,buf[di]
mov cx,6
mov al,1
L3:
shl bx,1;左移6次,判断cf是否为1
jnc no
loop L3
jmp yes
yes:
ret
no:
mov al,0
ret
judge endp
4.源程序与执行结果
4.1源程序代码
.386
data segment use16
many db 'How many numbers do you want?(0~9)? $'
tip db 'Please input a number(0~65535): $'
next db 'Do you want to go on (input Y or N )?$'
nice db 'The numbers meet your requirements: $'
fail db 'There is something wrong in your input! Try again! $'
toll db ' numbers meet your requirements.$'
nextword db ?
buf dw 10 dup(0);设置buf区域保存转换后的数字
string db 10;设置字符串输入区域
db 0
db 10 dup(0)
claf db 0dh,0ah,'$'
data ends
stack segment use16 stack
db 200 dup(0)
stack ends
code segment use16
assume cs:code,ss:stack,ds:data
srart:
mov ax,data
mov ds,ax
L8: mov di,0
mov ah,9
lea dx,many;输入提示数字多少的提示语句
int 21h
call clafp
mov ah,1
lea dx,nextword
int 21h
mov ah,0
sub al,30h
mov cx,ax;将输入次数保存到cx
call clafp
L1:
call cin;调用子程序输入字符串
cmp cx,0
jnz L1
mov di,0
mov cx,0
lea dx,nice;输出提示性字符串
int 21h
call clafp
L6: push cx
call judge
pop cx
cmp al,0;判断是否满足要求
jz L7
inc cx
call print
L7: add di,2
cmp di,20;判断是否读取完毕
jnz L6
mov dx,cx
add dl,30h
mov ah,2
int 21h
lea dx,toll;输出符合要求的总数
mov ah,9
int 21h
call clafp
L9: lea dx,next
int 21h
lea dx,nextword
mov ah,1
int 21h
call clafp
cmp al,'Y';判断是否为Y 或者 y
jz L8
cmp al,'y'
jz L8
cmp al,'N'
jz L5
cmp al,'n'
jz L5
lea dx,fail
mov ah,9
int 21h
call clafp
jmp L9
L5:
mov ah,4ch
int 21h
;----------
;子程序功能:换行
;使用到的寄存器:
;dx:保存偏移地址
;ah:调用中断
;------------
clafp proc
lea dx,claf
mov ah,9
int 21h
ret
clafp endp
;------------
;子程序功能:输入字符串
;使用到的寄存器
;cx:记录输入字的数量
;ah:调用中断
;dx:保存偏移地址
;------------------
cin proc
dec cx
lea dx,tip;输出提示性字符串
mov ah,9
int 21h
call clafp
mov ah,10
lea dx,string;输入字符串
int 21h
push cx
call tonum;将字符串转化成10进制数
cmp al,1;判断是否满足要求
jz L4
pop cx
inc cx
push cx
L4: pop cx
call clafp
ret
cin endp
;-----------------------
;子程序功能:将字符串转化成10进制数
;用到的寄存器:si源字符串
;di指向目标地址
;cx保存字符串长度
;ax保存转换的字符
;bl保存每一位的字符
;----------------------------
tonum proc
mov si,2
mov cl,string+1;判断字数是否超出范围
cmp cl,5
ja err
mov ch,0
xor ax,ax
L2:
mov bl,string[si]
inc si
cmp bl,'9';判断每一位是否符合要求
ja err
cmp bl,'0'
jb err
sub bl,'0'
mov bh,0
mov dx,10;乘以10在加个位数
mul dx
jc err
add ax,bx
jc err
loop L2
mov buf[di],ax
add di,2
mov al,1
ret
err:;如果错误则输出错误信息
lea dx,fail
mov ah,9
int 21h
lea dx,claf
int 21h
mov al,0
ret
tonum endp
;-----------------------
;子程序功能:将字型数字输出
;用到的寄存器:
;si源字,在子程序前应该赋值
;ax,dx用于除法
;bx用作除数
;---------------------
print proc
mov ax,buf[di]
mov dx,0
mov bx,10000;将10进制的每一位输出
div bx;这里时间紧不做化简
push dx
mov dl,36h
mov ah,2
int 21h
pop ax
mov dx,0
mov bx,1000
div bx
push dx
mov dl,al
mov ah,2
add dl,30h
int 21h
pop ax
mov dx,0
mov bx,100
div bx
push dx
mov dl,al
mov ah,2
add dl,30h
int 21h
pop ax
mov dx,0
mov bx,10
div bx
push dx
mov dl,al
mov ah,2
add dl,30h
int 21h
pop ax
mov dx,0
mov bx,1
div bx
mov dl,al
mov ah,2
add dl,30h
int 21h
lea dx,claf
mov ah,9
int 21h
ret
print endp
;---------------
;子程序功能:判断十进制数是否满足前6位为1
;用到的寄存器
;bx:保存10进制数
;cx:保存1的个数
;返回参数:若满足要求al=1,否则al=0
;--------------------
judge proc
mov bx,buf[di]
mov cx,6
mov al,1
L3:
shl bx,1;左移6次,判断cf是否为1
jnc no
loop L3
jmp yes
yes:
ret
no:
mov al,0
ret
judge endp
code ends
end srart
4.2 测试
4.2.1 测试用例
输入数字:1
- 错误输入
66666
- 错误输入
2313h
- 正确输入
65500
是否继续:Y
输入数字:2
- 错误输入
123456
- 错误输入
8940.3
- 正确输入
54321
- 正确输入
65432
4.2.2 测试结果(运行截图)
5.参考资料
1)《80X86汇编语言程序设计(王元珍等)》
2)《汇编语言(王爽第3版)》