标题:请教一下这段代码的后续编写
只看楼主
oped02
Rank: 2
等 级:论坛游民
帖 子:39
专家分:20
注 册:2022-10-16
结帖率:100%
已结贴  问题点数:20 回复次数:7 
请教一下这段代码的后续编写
countkind.rar (843 Bytes)
搜索更多相关主题的帖子: 代码 编写 
2022-11-29 17:20
Valenciax
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:11
帖 子:337
专家分:2462
注 册:2016-5-15
得分:0 
随便写一个,可以参考一下
程序代码:
DATA SEGMENT

 Counter DB 0,0,0             ;数字,小写,大写...的数量
 result db 10,13,'Number('    ;结果字串
 N_num db 0,0,'), LowerLetter('    ;数字总量字串
 L_num db 0,0,'), UpperLetter('    ;小写总量字串
 U_num db 0,0,')',10,13,'$'    ;大写总量字串
 Addr_Off dw offset N_num,offset L_num,offset U_num    ;各总量地址
DATA ENDS
Code SEGMENT
ASSUME CS: Code,DS: DATA
START:

 MOV AX, DATA

 MOV DS, AX

 mov cx,100        ;限制数量
 cld            ;正向
Readkey:

 mov ah,1        ;读键
 int 21h        ;调用dos
 cmp al,0dh        ;是否回车
 jz Done        ;是,跳
 mov bx,0          ;bx = 0,数字数量位置
 cmp al,'0'        ;比较'0'
 jb Readkey        ;少于,其他字符,重来
 cmp al,'9'        ;比较'9'
 jbe Counting        ;少于,0~9内,跳counting
 mov bx,2        ;bx = 2,大写数量位置
 cmp al,'A'        ;比较'A'
 jb Readkey        ;少于,其他字符,重来
 cmp al,'Z'        ;比较'Z'
 jbe Counting        ;少于,A~Z内,跳counting
 mov bx,1        ;bx = 1,小写数量位置
 cmp al,'a'        ;比较'a'
 jb Readkey        ;少于,其他字符,重来
 cmp al,'z'        ;比较'z'
 ja Readkey        ;大于,其他字符,重来
Counting:

 inc byte ptr Counter[bx]    ;以bx作为索引,加对应(0.1或2)的数量
 loop Readkey        ;下一个
Done:

 mov cx,3        ;=3
 mov bx,offset Addr_Off    ;结果字串地址
 mov si,offset Counter    ;元素数量起始
@@:

 lodsb            ;al=ds:[si], si+1
 aam            ;bcd调整,若al=0Ch,aam后,ax=0102
 or ax,3030h        ;转为ascii字符
 xchg al,ah        ;交换
 mov di,[bx]        ;取相应的数量字串地址
 mov [di],ax        ;存入数字符
 add bx,2        ;下一组
 loop @b        ;回圈,跳到上一个@@:
 mov ah,9        ;输出函数
 mov dx,offset result    ;结果地址
 int 21h        ;调用dos
 mov ah,4ch        ;离开
 int 21h        ;调用dos

Code ENDS
END START
2022-11-29 18:25
oped02
Rank: 2
等 级:论坛游民
帖 子:39
专家分:20
注 册:2022-10-16
得分:0 
回复 2楼 Valenciax
请教一下版主,Addr_Off dw后面三个offset该怎么使用啊
2022-11-29 22:18
Valenciax
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:11
帖 子:337
专家分:2462
注 册:2016-5-15
得分:0 
显示结果是

Number(10), LowerLetter(09), UpperLetter(09)

其实是预先把数字放入对应的位置,只做一次int21,ah=9,
就是
1.Number(     ;之后的位置放数字量
2.LowerLetter(    ;之后的位置放小写量
3.UpperLetter(    ;之后的位置放大写量

但这3位置并不均一,先想想怎么写....

举一个另外的例子,你会明白这个写法的使用时机.
现在一个程式里,有20句英文句子,长短不一(短的几个字,长的超过100),用户可以键入1~20,然后程式会根据'输入数字'显示对应的句子,

比如输入1,会显示
I have had my invitation to this world's festival, and thus my life has been blessed.(80bytes,含回车)

比如输入2,会显示
Give me the strength lightly to bear my joys and sorrows.
Give me the strength to make my love fruitful in service.
Give me the strength never to disown the poor or bend my knees before insolent might.
Give me the strength to raise my mind high above daily trifles.
And give me the strength to surrender my strength to thy will with love.(342bytes含回车)


我们在资料段建立20个字串组.

sentence01 db 'I have had my invitation to this world's festival, and thus my life has been blessed.(80bytes,含回车)'

sentence02 db 'Give me the strength lightly to bear my joys and sorrows.'
db 'Give me the strength to make my love fruitful in service.'
...
...

sentence03 ....
....
....
....

sentence20
...
...


然后,如何处理用户的输入?

方法1.
做20个比较,比较1,不是,比较2,不是......对了,是15,于是显示no.15的句子.....

方法2.
建立'字串组'时,以最长的句子(342)作均长,弹性一点,设定350好了,然后

sentence01 db '... (总长350)
sentence02 db '... (总长350)
..
sentence20 db '... (总长350)

用户输入15时,用14x350,指向15句子的位置,再显示.
这方法是空间换取简便,只要资料长短比较均一,是可取的.

方法3.
把所有'句子地址的起点'串联起来,另外建立一个索引数组

Addr_off dw offset sentence01,offset sentence02.,....,offset sentence20

这里,每一个地址2bytes.
用户输入15时,只要
mov bx,userinput    ;输入值
shl bx,2        ;x2 ,转为word
mov ax,Addr_off[bx]    ;取得该句子的起始位置

这就是上面
Addr_Off dw offset N_num,offset L_num,offset U_num 的使用时机,
将不同的地址串联起来另做一个索引数组,只要知道索引值,就可以直接取得地址.
而不必做多次比较(方法1),根据每一次比较去作决定,这种累赘没效率的写法.




2022-11-30 03:45
oped02
Rank: 2
等 级:论坛游民
帖 子:39
专家分:20
注 册:2022-10-16
得分:0 
感谢版主回答
我还想再请教您一下,逐个输入字符再匹配这个思想我已经有所收获
但是如果我直接开辟一个缓冲区
比如
str db 100,?,100 dup(?)
使用0ah功能调用的话该怎么解决这个问题呢?
我的想法是输入后再逐个取出比较,但这样的话还不如直接使用01h
2022-11-30 12:25
oped02
Rank: 2
等 级:论坛游民
帖 子:39
专家分:20
注 册:2022-10-16
得分:0 
buffer.rar (656 Bytes)
2022-11-30 13:19
Valenciax
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:11
帖 子:337
专家分:2462
注 册:2016-5-15
得分:20 
其实差别不大,不同在于0Ah函式可以保留原字串...

程序代码:
DATA SEGMENT
 Counter DB 0,0,0             ;数字,小写,大写...的数量
 result db 10,13,'Number('    ;结果字串
 N_num db 0,0,'), LowerLetter('    ;数字总量字串
 L_num db 0,0,'), UpperLetter('    ;小写总量字串
 U_num db 0,0,')',10,13,'$'    ;大写总量字串
 Addr_Off dw offset N_num,offset L_num,offset U_num    ;各总量地址
 StringInput db 100,?,100 dup (?)            ;输入缓冲

DATA ENDS
Code SEGMENT
ASSUME CS: Code,DS: DATA
START:
 MOV AX, DATA
 MOV DS, AX
 cld            ;正向
 lea dx, StringInput    ;取输入缓冲地址
 mov ah,0Ah        ;输入字串函式
 int 21h        ;调用dos
 lea si,StringInput+2    ;实际输入地址
 xor cx,cx        ;cx=0
 mov cl,[si-1]        ;取实际输入字符数
 jcxz exit        ;若cx=0,即无输入,离开
Reload:
 lodsb             ;al=ds:[si], si+1    
 cmp al,0dh        ;是否回车
 jz Done        ;是,跳
 mov bx,0          ;bx = 0,数字数量位置
 cmp al,'0'        ;比较'0'
 jb Reload        ;少于,其他字符,重来
 cmp al,'9'        ;比较'9'
 jbe Counting        ;少于,0~9内,跳counting
 mov bx,2        ;bx = 2,大写数量位置
 cmp al,'A'        ;比较'A'
 jb Reload        ;少于,其他字符,重来
 cmp al,'Z'        ;比较'Z'
 jbe Counting        ;少于,A~Z内,跳counting
 mov bx,1        ;bx = 1,小写数量位置
 cmp al,'a'        ;比较'a'
 jb Reload        ;少于,其他字符,重来
 cmp al,'z'        ;比较'z'
 ja Reload        ;大于,其他字符,重来
Counting:
 inc byte ptr Counter[bx]    ;以bx作为索引,加对应(0.1或2)的数量
 loop Reload        ;下一个

Done:
 mov cx,3        ;=3
 mov bx,offset Addr_Off    ;结果字串地址
 mov si,offset Counter    ;元素数量起始
@@:
 lodsb            ;al=ds:[si], si+1
 aam            ;bcd调整,若al=0Ch,aam后,ax=0102
 or ax,3030h        ;转为ascii字符
 xchg al,ah        ;交换
 mov di,[bx]        ;取相应的数量字串地址
 mov [di],ax        ;存入数字符
 add bx,2        ;下一组
 loop @b        ;回圈,跳到上一个@@:
 mov ah,9        ;输出函数
 mov dx,offset result    ;结果地址
 int 21h        ;调用dos
exit:
 mov ah,4ch        ;离开
 int 21h        ;调用dos

Code ENDS
END START
2022-11-30 13:51
oped02
Rank: 2
等 级:论坛游民
帖 子:39
专家分:20
注 册:2022-10-16
得分:0 
回复 7楼 Valenciax
原来如此,只要再使用字符串指令就能解决了
十分感谢,祝您生活愉快
2022-11-30 19:59



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-510813-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016167 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved