要求:
从键盘输入一字符串,统计数字、大写字母、小写字符和其它字符个数,分别用十六进制和十进制显示出来;
结果:
代码:
; multi-segment executable file template.
data segment
; add your data here!
pkey db "press any key...$"
ibuf db 255 ;第1个字节填入可能输入的最大字符数
db 0 ;第2个字节用于存放实际输入的字符数
db 255 dup(0) ;重复次数255,重复内容为0,字符串存放区
dnum db 0 ;数字个数,'0'-'9'
dxnum db 0 ;大写字母个数 'A'-'Z'
xxnum db 0 ;小写字母个数 'a'-'z'
qtnum db 0 ;其他字符个数 other
asc db 32,32,32,32,'$' ;32表空格
dem db 32,32,32,32,'$'
string db 'number NN CN LN ON $'
string1 db 0dh,0ah,'dec display:','$'
string2 db 0dh,0ah,'hex display:','$'
strstart db 'Please input a string of random characters, numbers and symbols: $'
ends
stack segment
dw 128 dup(0)
ends
code segment
assume cs:code,ds:data ,ss:stack
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
lea dx, pkey ;lea 将存储器操作数的有效地址传送dx数据寄存器
mov ah, 9
int 21h ;调用DOS功能,该功能为显示DS:DX地址处的字符 output string at ds:dx
; wait for any key....
mov dl,0dh ;0D是回bai车符的duASCII码
mov ah,02 ;输出一个字符
int 21h
mov dl,0ah ;0a表换行
mov ah,02 ;输出一个字符
int 21h ;DOS功能调用进行换行
; add your code here
;————————提示信息
lea dx, strstart
mov ah, 9
int 21h
mov dl,0dh
mov ah,02
int 21h ;回车
mov dl,0ah
mov ah,02
int 21h ;换行
;————————输入字符串
mov dx,offset ibuf ;变量ibuf的地址赋给dx
mov ah,0ah ;输入一个字符串 ,DS:DX = 输入字符串
int 21h
;————————统计
mov si,1 ;si=1
mov cl,ibuf[si] ;指向一个字符(存放实际字符个数),CX计数器,循环次数
mov ch,0
inc si ;si寄存器加一
tol1:
mov al,ibuf[si] ;ax累加器,
cmp al,'0' ;比较al与0,
jb other ;条件满足:al<'0',转移,计算其他字符
cmp al,'9'
jbe numsum ;条件满足:al<='9',转移,计算数字'0'-'9'
cmp al,'A'
jb other ;条件满足:al<'A',转移,计算其他字符
cmp al,'Z'
jbe capsum ;条件满足:al<='Z',转移,计算大写字符'A'-'Z'
cmp al,'a'
jb other ;条件满足:al<'a',转移,计算其他字符
cmp al,'z'
jbe lowsum ;条件满足:al<='a',转移,计算小写字符'a'-'z'
other:
inc qtnum ;A2num加1
jmp next ;跳到标号next位置
numsum:
inc dnum
jmp next
capsum:
inc dxnum
jmp next
lowsum:
inc xxnum
next:
inc si ;si指针加1
loop tol1 ;循环
;————————提示信息
call dpcrlf
call dpcrlf
lea dx, string
mov ah, 9
int 21h
mov dx,offset string1 ;指定字符串在数据段地偏移地址
mov ah,09
int 21h ;显示字符串
;————十进制显示
disp:
mov cx,4 ;cx=4,循环次数
mov di,offset dnum ;DI获取变量dnum地址
disp1: ;外循环
mov bl,10
mov al,[di] ;获得dnum变量值
mov si,2 ;循环次数2
disp2: ;内循环
mov ah,0 ;ah高位赋0
div bl; ;AX/bl的商=AL,AX/BL的余数=AH
add ah,30h;
mov asc[si],ah ;ah余数
dec si ;si减一
cmp si,0
jge disp2 ;条件满足:si>=0,转移disp2
mov dx,offset asc ;获取asc的地址
mov ah,9
int 21h ;显示DS:DX地址处的字符
inc di ;di+1,换到dxnum的地址,这几个变量的地址连续,故加1便可访问
loop disp1
;————十六进制显示
mov dx,offset string2 ;指定字符串在数据段地偏移地址
mov ah,09
int 21h ;显示字符串
mov cx,4
mov di,offset dnum
hecdisp:
mov bl,[di]
call bin_hec
inc di
loop hecdisp
mov ax, 4c00h ; exit to operating system.
int 21h
bin_hec proc near
mov dl,bl
shr dl,4 ;算数右移,高四位变为低四位
or dl,30h ;高四位变3,相当于加30h
cmp dl,39H ;是0-9,还是0A-0FH(A-F十六进制位41H-46H)
jbe AD1 ;dl<=39H,满足跳转
add dl,7 ;数值在0AH-0FH,Ascii码值加上7
AD1:
mov ah,2 ;输出一个字符
int 21h ;高四位值输出,dl
mov dl,bl
and dl,0FH ;取低4位
or dl,30H ;高四位变3
cmp dl,39H
jbe AD2
ADD dl,7
AD2:
mov ah,2 ;输出一个字符
int 21h ;低四位值输出,输出dl
mov dl,'H'
mov ah,2
int 21H
mov dl,20h ;20h表空格
mov ah,02 ;输出一个字符
int 21h
ret
bin_hec endp
dpcrlf proc ;光标回车换行的子程序
push ax
push dx
mov ah, 2
mov dl, 0dh
int 21h
mov ah, 2
mov dl, 0ah
int 21h
pop dx
pop ax
ret
dpcrlf endp
ends
end start ; set entry point and stop the assembler.