您的位置:首页 > 其它

汇编 统计字符个数

2013-11-12 22:06 260 查看
实验四要做的是:分类统计字符的个数

实验要求:1.接收从用户键入的一串字符(不超过80,用回车结束)。2.按字母,数字,其他字符分类进行计数,然后将结果存入以letter,digit,和other为名的存储单元中。

模块1 main 为总控模块

输入:从键盘输入一串字符

输出:显示每类数据的数目

功能:根据输入的字符,若某类数据出现一次则其所对应的存储单元中的数增加1.可以将数目存到某一寄存器中,将该数据存入存储单元中

模块2 input 为输入模块

输入:从键盘输入一串字符串

输出:输出到一个字符串数组中

功能:调用子模块crlf实现回车换行的功能

模块3 count 为计数模块

输入:从input模块中取得一个字符

输出:将各种字符的数目存入相应的存储单元中

功能:算法是,从字符串数组中取出一个字符,判断属于哪种类型,若属于letter,则letter相应

的寄存器中加1,同理别的也是这样(此处需要几个分支),判断是否结束,若结束,则该

字符串结束,将对于的寄存器中的数目移到相应的存储单元中。

模块4:output 从存储单元中取出数目输出

输入:存储单元取出16进制的数目

输出:将数目转换成10进制数字输出

功能:将存储单元中的数据转换成10进制后输出到屏幕上,调用crlf子模块,实现换行的功能

模块5:crlf 回车换行的功能

自己写的代码:

data segment ;定义数据段

input1 db 80,?,80 dup(?) ;定义输入字符串的缓冲区,数目最大为80

print db 'Input the sentence:','$' ;提示输入要计数的句子

mes1 db 'The number of letter is','$' ;提示输出letter的数目

mes2 db 'The number of digit is','$' ;提示输出digit的数目

mes3 db 'The number of other is','$' ;提示输出other的数目

crlf1 db 13,10,'$' ;回车换行

letter dw ? ;定义一个存储空间来存letter数目

digit dw ? ;定义一个存储空间来存储digit数目

other dw ? ;定义一个存储空间来存储other数目

data ends

;***********************************************************************

code segment ;定义程序段

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

main proc far

assume cs:code,ds:data

start:

;建立一个栈用于返回

push ds

sub ax,ax

push ax

;将ds设为当前的数据段

mov ax,data

mov ds,ax

sub ax,ax ;初始化letter,digit,other

mov letter,ax

mov digit,ax

mov other,ax

lea dx,print ;打印输入数据提示符

mov ah,09h

int 21h

call input ;调用input子模块来输入字符串

call count ;调用count子模块来处理字符串

call output ;调用output子模块来输出结果

main endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

input proc near

lea dx,input1 ;从缓冲区输入字符串

mov ax,0ah

int 21h

mov cl,[input1+2] ;获得输入的字符串的长度

cbw

mov SI,input1+3 ;获得第一个字符的位置

ret ;返回

input endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

count proc near

begin :

mov bx,[SI] ;获得SI所指的位置的字符

c0:

cmp bx,'0'

jnb c1

jb c7 ;若小于‘0’则为other

c1:

cmp bx,'9'

jna c8 ;是数字的情况

ja c2 ;否则判断是否是letter

c2:

cmp bx,'A'

jnb c3

jb c7 ;若是小于‘A’的则为other

c3:

cmp bx,'Z'

jna c6 ;若不大于则是letter

ja c4 ;若大于则判断是否是小写

c4:

cmp bx,'a'

jnb c6 ;若是不小于则为letter

jb c7 ;若小于则为other

c5:

cmp bx,'z'

jna c6 ;不大于则是letter

ja c7 ;若大于‘z’则是其他的字符

c6:

lea ax,letter

inc ax

mov letter,ax

cmp cx,0

jz output ;若cx为0则已经处理完毕进行输出

jnz rebegin ;否则到rebegin

c7: ;other的情况

lea ax,other

inc ax

mov other,ax

cmp cx,0

jz output ;若cx为0则已经处理完毕进行输出

jnz rebegin ;否则到rebegin

c8: ;digit的情况

lea ax,digit

inc ax

mov digit,ax

cmp cx,0

jz output ;若cx为0则已经处理完毕进行输出

jnz rebegin ;否则到rebegin

rebegin:

inc SI ;取下一个

jmp begin

ret

count endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

output proc near

lea dx,mes1 ;显示打印letter数目的提示符

mov ax,09h

int 21h

lea dx,letter ;将letter数目打印

int 21h

call crlf ;回车换行

lea dx,mes2 ;显示打印digit数目的提示符

int 21h

lea dx,digit ;将digit数目进行打印

int 21h

call crlf ;回车换行

lea dx,mes3 ;显示打印other数目的提示符

int 21h

lea dx,other ;将other数目进行打印

int 21h

call crlf ;回车换行

mov ah,4ch ;打印完毕退出

int 21h

ret

output endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

crlf proc near ;打印回车换行

mov ah,09h

lea dx,crlf1

int 21h

ret

crlf endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

code ends

end start

代码编译没有任何错误,但是,在运行时就会出现一个奇怪的对话框:



给老师发了一个邮件,很开心,老师很快就给回复了,

1.地址与单元内容的助记符的使用不对;

2.数据定义有问题,我们的字符都是用字节定义的;

以下是修改过的代码:

data segment ;定义数据段

input1 db 80,?,80 dup(?) ;定义输入字符串的缓冲区,数目最大为80

print db 'Input the sentence: ','$' ;提示输入要计数的句子

mes1 db 'The number of letter is ','$' ;提示输出letter的数目

mes2 db 'The number of digit is ','$' ;提示输出digit的数目

mes3 db 'The number of other is ','$' ;提示输出other的数目

crlf1 db 13,10,'$' ;回车换行

letter db ? ;定义一个存储空间来存letter数目

digit db ? ;定义一个存储空间来存储digit数目

other db ? ;定义一个存储空间来存储other数目

data ends ;sdfffg’’’’

;***********************************************************************

code segment ;定义程序段

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

main proc far

assume cs:code,ds:data

start:

;建立一个栈用于返回

push ds

sub ax,ax

push ax

;将ds设为当前的数据段

mov ax,data

mov ds,ax

sub ax,ax ;初始化letter,digit,other

mov letter,al

mov digit,al

mov other,al

lea dx,print ;打印输入数据提示符

mov ah,09h

int 21h

call input ;调用input子模块来输入字符串

call crlf

call count ;调用count子模块来处理字符串

;call output ;调用output子模块来输出结果

mov ah,4ch ;

int 21h

main endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

input proc near

lea dx,input1 ;从缓冲区输入字符串

mov ah,0ah

int 21h

mov cl,[input1+1] ;获得输入的字符串的长度

lea SI,input1+2 ;获得第一个字符的位置

ret ;返回

input endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

count proc near

begin :

mov bl,[SI] ;获得SI所指的位置的字符

c0:

cmp bl,'0'

jnb c1

jb c7 ;若小于‘0’则为other

c1:

cmp bl,'9'

jna c8 ;是数字的情况

ja c2 ;否则判断是否是letter

c2:

cmp bl,'A'

jnb c3

jb c7 ;若是小于‘A’的则为other

c3:

cmp bl,'Z'

jna c6 ;若不大于则是letter

ja c4 ;若大于则判断是否是小写

c4:

cmp bl,'a'

jnb c6 ;若是不小于则为letter

jb c7 ;若小于则为other

c5:

cmp bl,'z'

jna c6 ;不大于则是letter

ja c7 ;若大于‘z’则是其他的字符

c6:

mov al,letter

inc al

dec cl

mov letter,al

cmp cl,0

jz output1 ;若cx为0则已经处理完毕进行输出

jnz rebegin ;否则到rebegin

c7: ;other的情况

mov al,other

inc al

dec cl

mov other,al

cmp cl,0

jz output1 ;若cx为0则已经处理完毕进行输出

jnz rebegin ;否则到rebegin

c8: ;digit的情况

mov al,digit

inc al

dec cl

mov digit,al

cmp cl,0

jz output1 ;若cx为0则已经处理完毕进行输出

jnz rebegin ;否则到rebegin

rebegin:

inc SI ;取下一个

jmp begin

output1:

call output

ret

count endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

output proc near

lea dx,mes1 ;显示打印letter数目的提示符

mov ah,09h

int 21h

mov dl,letter ;将letter数目打印

or dl,30h

mov ah,02h

int 21h

call crlf

lea dx,mes2 ;显示打印digit数目的提示符

mov ah,09h

int 21h

mov dl,digit ;将digit数目进行打印

or dl,30h

mov ah,02h

int 21h

call crlf

mov ah,09h

lea dx,mes3 ;显示打印other数目的提示符

int 21h

mov ah,02h

mov dl,other ;将other数目进行打印

or dl,30h

int 21h

call crlf ;回车换行

ret

output endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

crlf proc near ;打印回车换行

mov ah,09h

lea dx,crlf1

int 21h

ret

crlf endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

code ends

end start

通过对比发现主要问题果然就是老师说的几个问题:

1.定义时我使用了dw的定义方式,当时的想法是一个整形的数字要占用4个字节,所以就定义了一个dw的类型 ,现在想想,一个字节就可以记录句子中字符的数目

2.对于输入的那个字符区的定义不甚了解,开始的做法就是老师修改的那样,然后出了错后想,定义的字符应该也占一个位置吧,就变成了上面的程序那个样子。。。。

3.对于寄存器的了解不够,每个寄存器是16位的,数字定义成字节类型的话,只需要低位或者高位就可以。

刚开始时,地址觉得是8位的,所以将地址都扩展以后存入寄存器,现在想想,是可以直接存入低位或者高位二者之一就可以了呀,否则的话,后面要取也很麻烦
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: