code segment
assume cs:code
org 100h
start:jmp begin
stra db 254
strn db ?
strr db 254 dup(?)
arr db 254 dup(?)
arrn db 254 dup(0)
begin:push cs
pop ds
push cs
pop es
lea dx,stra
mov ah,10
int 21h
lea si,strr ; 字符串首地址置于si
lea di,arr ; 字符串中字符存于的备用首地址置于di
mov cl,strn ; 输入的字符数
mov ch,0 ;
mov dx,0 ; 不重复的字符数
cld ; 清方向标志
lodsb ; 装入第一个字符
inc byte ptr[di+254] ; 第一个字符计数器增1
stosb ; 存入第1个字符
inc dx ; dx由0变1
dec cx ; 输入的字符数减1
@1:
push cx ; 保存外循环的cx
mov cx,dx ; 将已统计出的不重复的字符数置于计数器cx
lodsb ; 装入下一个输入的字符到al
lea di,arr ; 置不重复的字符保存的首地址
repne scasb ; 只要al与在arr中已保存的不相等则循环扫描
je @2 ; 若找到有相同的 转@2
lea di,arr ; 没有找到则是新出现的字符,取arr首地址
add di,dx ; 加上dx后 di指向紧邻的空白处
inc byte ptr [di+254]; 将对应的计数器增1
stosb ; 将新字符保存到空白处
inc dx ; 不重复字符数增1
jmp @3 ; 转 @3
@2:
inc cx ; cx指向找到的相同的元素的上一个元素处
mov ax,dx ; 已有元素总数置于ax
sub ax,cx ; 计算找到的元素在arr中的相对位置
lea di,arr ; 取arr首地址
add di,ax ; 计算找到的元素在arr中的绝对位置
inc byte ptr[di+254] ; 相应的计数器加1
@3:
pop cx ; 恢复外循环的计数器
loop @1 ; 循环
push dx
mov ah,2
mov dl,13 ; 回车
int 21h
mov dl,10 ; 换行
int 21h
pop dx
mov cx,dx
lea si,arr
@4:
mov dl,[si] ; 输出字符
mov ah,2
int 21h
mov dl,32 ; 输出空格
int 21h
mov dl,[si+254]
mov al,dl
mov ah,0
mov bl,10
div bl
push ax
mov dl,al ; 输出字符个数的十位数字
add dl,30h
mov ah,2
int 21h
pop ax
mov dl,ah ; 输出字符个数的个位数字
add dl,30h
mov ah,2
int 21h
mov dl,13 ; 回车
int 21h
mov dl,10 ; 换行
int 21h
inc si
loop @4
mov ah,4ch
int 21h
code ends
end start