回 帖 发 新 帖 刷新版面

主题:各位高手帮帮小弟啊

从键盘上输入一个以“$”结束的字符串,显示该字符串中,数字的个数、大写字母的个数、小写字母的个数和其他符号的个数
各位高手帮帮我!

回复列表 (共5个回复)

沙发

你看一下下面的三个子程序吧,它们应该可以帮你搞定的,五楼的程序可以运行出结果,你可以改数据段的msg,

板凳


data segment
   value1 dw 256
   str db 16 dup (30h),13,10;定义一个存放字符串的数组str,赋初值为0的
                            ;ASCII码。后面再加上回车换行的ASCII码
data ends
code segment
  assume cs:code,ds:data
start:
      mov ax,data
      mov ds,ax                 ;装入段地址

      ;下面是求的value1的二进制字符串的程序段
      mov ax,value1             ;取出value1的值给ax
      mov bx,offset str         ;取出要输出字符串的偏移地址
again:                          
      sal ax,1                  ;通过数据在内存中是以补码形式存放的特点 
      jnc lp                    ;以算术左移来实现从高位到低位的字符按位
      mov byte ptr [bx],31h     ;取得,然后判断是否为1,当为1时将31h传送
lp:                             ;给对应位,即1的ASCII码
                               
      inc bx                    ;字符串数组偏移地址加1
      cmp ax,00                 ;判断左移一位后ax中的值是否为0,
      jnz again                 ;当不为0时还有有效位,继续循环

      ;下面是输出字符串的程序段
      mov cx,18                 ;加上回车换行共18个字符
      mov bx,offset str         ;取要输出字符串的有效地址
pp:
      mov dl,byte ptr [bx]      ;取出一个字符的ASCII码送入dl
      mov ah,2                  ;送中断参数2给ah,说明调用输出字符功能
      int 21h                   ;调用21号中断
      inc bx                    ;字符串地址偏移地址加1
      loop pp                   ;cx不为0继续循环输出
      
      ;返回dos
      mov ah,4ch                
      int 21h
code ends
     end start

3 楼


data segment
   value2 dw 4811
   str db 4 dup (30h),13,10 ;定义一个str数组存放要输出的16进制字符串,后面加回车换行
data ends
code segment
  assume cs:code,ds:data
start:
      mov ax,data
      mov ds,ax              ;装入段地址

      ;下面依据value2在内存中是以补码形式存放的特点,四位一组取出对应的十进制值给str
      mov ax,value2          ;取出value2的值给ax
      mov bx,offset str+4-1  ;取出str的第四个元素偏移地址给bx
      mov cl,4               ;因为后面要右移四位,所以将4赋值给cl
again:
      mov dx,ax              ;后面要改变ax的值,所以先送入dx保存
      and dl,0fh             ;相与取出dx中的最低四位,即一个16进制数
      mov byte ptr [bx],dl   ;将取出的数送入str保存
      shr ax,cl              ;逻辑右移为下次取一个16进制数做准备
      dec bx                 ;因为是从低位向高位取,bx减1,按照存储器的高高低低原则
      cmp ax,00              ;判断ax是否为0,
      jnz again              ;不为0继续取有效位

      ;下面是将取到的每一位十进制数转化成对应十六进制数的ASCII码
      mov bx,offset str      ;取要转化的字符串的偏移地址
      mov cx,4               ;对应四个16进制数的ASCII码
l:
      mov dl,byte ptr [bx]   ;取出一个对应的十进制数值给dl进行处理
      cmp dl,0ah             ;与10比较判断
      jb next                ;当小于10时转移到next
      add dl,7h              ;否则dl中的值加7
next:
      add dl,30h             ;给dl中的值加30h
      mov byte ptr [bx],dl   ;将得到的对应16进制数的ASCII码再送入str数组保存,为输出作准备
      inc bx                 ;str的偏移地址加1
      loop l                 ;cx不为0继续循环处理

      ;下面是真正输出value2对应的16进制字符串形式
      mov cx,6
      mov bx,offset str
pp:
      mov dl,byte ptr [bx]
      mov ah,2
      int 21h
      inc bx
      loop pp
      ;输出结束,返回dos
      mov ah,4ch
      int 21h
code ends
     end start

4 楼


data segment
   str db 2 dup (?)  ;定义一个str数组存放每次要输出的16进制数的ASCII码值
data ends
code segment
  assume cs:code,ds:data
start:
      mov ax,data     ;装入数据段段地址
      mov ds,ax
      mov ax,0000h    ;装如附加段的段地址
      mov es,ax
      mov si,0000h    ;置si为每次取出内存0000:0000地址单元数据的指针
      mov bx,0000h    ;置bx为计数寄存器,共要取出100个数
zp:
      inc bx          ;计数器加1,对一个存储单元的数操作开始
      mov al,es:[si]  ;取出一个字节的内容给al  
      mov cl,4        ;置cl 为4,为移位 做准备
      mov dl,al       ;先把al中的数放入dl保存
      and dl,0fh      ;取出低四位
      mov str[1],dl   ;将取出的低四位放入str中保存
      shr al,cl       ;al右移四位
      and al,0fh      ;取出这次操作的存储单元的高四位
      mov str[0],al   ;将高四位放入str,还是本着高高低低的原则
;下面是对取出来字节的对应十进制数值转化成对应16进制数ASCII码的处理并输出
      mov di,offset str
      mov cx,2
l1:
      mov dl,byte ptr [di]
      cmp dl,0ah
      jb next
      add dl,7h
next:
      add dl,30h
      mov byte ptr [di],dl
      mov dl,byte ptr [di] ;求得对应的16进制ASCII码后将其送入dl,直接输出
      mov ah,2          
      int 21h
      inc di               ;修改di的值,将str的偏移地址加1
      loop l1              ;若cx不为0则继续处理
     ;输出空格
      mov ah,2             
      mov dl,20h   ;将空格的ASCII码值送入dl,准备输出   
      int 21h
      mov ax,bx    ;先把bx计数值送入ax保存
      and ax,000fh ;判断bx中的个数是否能被16整除
      jnz l2       ;不能被16整除时则跳转到l2
;下面时输出回车换行,也就是当满足被16整除时输出回车换行
      mov ah,02
      mov dl,13  ;将回车的ASCII 码值送入dl,为输出作准备
      int 21h
      mov ah,02
      mov dl,10 ;将换行的ASCII 码值送入dl,为输出作准备
      int 21h
l2:
      inc si     ;指针si 加1,为处理下个字节数据作准备
      cmp bx,100 ;判断操作数据个数是否到了100个
      jnz zp     ;小于100则继续处理
  ;处理完100个后返回dos 
      mov ah,4ch
      int 21h
code ends
     end start

5 楼



data1 segment
 msg db 'abcDF0984.#####.',0
data1 ends
code segment
 assume cs:code,ds:data1
start:

      mov ax,data1
      mov ds,ax
     
      lea dx,msg
      call count
      call dispbx
      mov bx,cx
      call dispbx
      mov bx,di
      call dispbx
      
exit:
     mov ah,4ch
     int 21h

upper proc 
      cmp al,'a'
      jb over1
      cmp al,'z'
      ja over1
      sub al,20h
  over1:
      ret
upper endp

count proc 
      push ax
      push si
      xor bx,bx
      xor cx,cx
      xor di,di
      mov si,dx
 again1:
      mov al,[si]
      inc si
      cmp al,0
      je over2
      cmp al,'0'
      jl other
      cmp al,'9'
      jg next1
      inc bx
      jmp again1
 next1:
      call upper
      cmp al,'A'
      jl other
      cmp al,'Z'
      jg other
      inc cx
      jmp again1
 other:
      inc di
      jmp again1
 over2:
      pop si
      pop ax
      ret
count endp


subdata segment
        db 5 dup('0'),0ah,0dh,'$'
subdata ends

dispbx proc 
       assume ds:subdata
       push ds
       push dx
       push cx
       push ax
       mov ax,subdata
       mov ds,ax
       cmp bx,0
       jge next2
       mov dl,'-'
       mov ah,2
       neg bx
  next2:
       mov si,4
       mov ax,bx
       mov cx,10d
 again2:
       xor dx,dx
       idiv cx
       add dl,'0'
       mov [si],dl
       dec si
       jge again2
       xor dx,dx
       mov ah,9
       int 21h
       pop ax
       pop cx
       pop dx
       pop ds
       ret
dispbx endp
code ends
end start

我来回复

您尚未登录,请登录后再回复。点此登录或注册