如何在装配中同时计算小字母和大字母?

时间:2015-04-13 16:02:29

标签: assembly x86

任何人都可以帮我组装!我知道如何计算小字母或大字母,但我不能同时做两件事。下面是我的小写字母代码

  mov   bx, offset buff
  mov   cl, [bx - 1]   ;size of string
  mov   dx, 0         ;reset dx
cykluss:   
  mov   al, [bx]   ;reading all characters
  inc bx         ;increasing char in string
  cmp al,'$'  ; end of line?
  je supp 
  cmp al,'a'
  JL cykluss  ; if char < 'a' then go to the start(cykluss)
  CMP al,'z'
  JG cykluss ; if char > 'z' then go to the start(cykluss)
  inc dx      
  jmp cykluss      

supp:
  mov bx,dx
  charp 10    ;macro for new line
  CALL DISP   ;convert from dx to number

请帮助我非常感谢

2 个答案:

答案 0 :(得分:1)

很高兴。你实际上试图先自己解决问题。不仅如此,您在源代码中提出了好的评论

这是我原创尝试的6分钟改造。我试图让你的标签完整无缺。请注意,注释包含一些空白区域,以便它们在页面上排列得更整齐。您会发现,基于整洁的代码,您可以获得一千倍的尊重。你几乎可以在世界范围内找到它。

哦,大免责声明:我没有运行这个,所以,请查看它是否适合您的调试器等等。

有一点需要注意:我使用了JAJB而不是JGJL。如果你在这里不知道为什么这很重要,请发表评论,我会详细介绍。

希望这会有所帮助;愉快地提供,你的自由,有退款保证......

   Mov   bx, offset buff
   Mov   cl, [bx - 1]               ;size of string
   Mov   dx, 0                      ;Dx will hold UPPERcase count
   Mov   cx, 0                      ;Cx will hold lowercase count

 cykluss:   

   Mov      al, [bx]                ;reading all characters
   Inc      bx                      ;increasing char in string

   Cmp      al,'$'                  ;end of line?
   Je       supp                    ;yes



                                    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                    ;;  Check for the byte between 'a' and 'z' ;;
                                    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

   Cmp      al,'a'                  ;Is it below lower case 'a' ?
   JB       Not_Lower_Case          ;Yes, so it's not lower case

   CMP      al,'z'                  ;Is it above lower case 'z' ?
   JA       Not_Lower_Case          ;Yes, so it's not lower case

   Inc      Cx                      ;Else, the byte is between 'a' and 'z' so count it
   Jmp      cykluss                 ;Go do the next char



                                    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                    ;;  Now, same thing for capital 'A' and 'Z';;
                                    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 Not_Lower_Case:

   Cmp      al,'A'                  ;Is it below upper case 'A' ?
   JB       Not_Upper_Case          ;Yes, so it's not lower case

   CMP      al,'Z'                  ;Is it above upper case 'Z' ?
   JA       Not_Upper_Case          ;Yes, so it's not lower case

   Inc      Dx                      ;Else, the byte is between 'A' and 'Z' so count it and drop through

 Not_Upper_Case:                    ;If we hit this label, it was neither upper nor lower

   Jmp      cykluss                 ;Go do the next char


                                    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                    ;;  Note to original poster, you now have  ;;
                                    ;;  two counters, one in Cx and the other  ;;
                                    ;;  in Dx such as you had in your attempt  ;;
                                    ;;  when you started. It is now up to you  ;;
                                    ;;  to put it into your macro to make the  ;;
                                    ;;  output work for both numbers instead.  ;;
                                    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


 supp:

   Mov bx,dx

   Charp 10                         ;macro for new line

   CALL DISP                        ;convert from dx to number

答案 1 :(得分:0)

只需复制粘贴并运行。

要检查小写和大写字母,您必须检查字符是否在极端字母之间:'A'和'z',如果是,检查字符是否大于或等于'a',如果是,它是小写字母,或者,检查字符是否小于或等于'Z',如果是,它是一个大写字母。明白了吗?接下来是您的代码,其中包含一些更改,以使其在EMU8086中运行:

.stack 100h
.data

buff db 'aB[C*E-G^h#$'

lower_counter dw 0 ;COUNTER FOR LOWERCASE LETTERS.
upper_counter dw 0 ;COUNTER FOR UPPERCASE LETTERS.

msj1 db 13,10,'lowercase letters : $'
msj2 db 13,10,'uppercase letters : $'

str db 6 dup('$') ;STRING TO STORE NUMBER. 

.code          
;INITIALIZE DATA SEGMENT.
  mov  ax,@data
  mov  ds,ax

  mov   bx, offset buff    
cykluss:   
  mov al, [bx]   ;reading all characters
  inc bx           ;increasing char in string
  cmp al,'$'       ; end of line?
  je supp 

;---CHECK LETTERS ON THE EXTREMES ('A','z').

  cmp al,'A'  ; if char < 'A' then IT'S NOT A LETTER.
  JL cykluss
  cmp al,'z'  ; if char > 'z' then IT'S NOT A LETTER.
  JG cykluss  ; if char > 'z' then go to the start(cykluss)

;---CHECK LETTERS IN THE MIDDLE ('Z','a').  
;---REMEMBER : IF NEXT LINES ARE EXECUTED, IT MEANS "AL"
;---HOLDS A VALUE BETWEEN 'A' AND 'z' (65..122).                                                        

  cmp al,'a'
  JGE its_lowercase ; if char >= 'a' then IT'S A LOWERCASE LETTER.
  CMP al,'Z'
  JLE its_uppercase ; if char =< 'Z' then IT'S AN UPPERCASE LETTER.
  jmp cykluss      ; if (char > 'Z') and (char < 'a') then IT'S NOT A LETTER.

its_lowercase:  
  inc lower_counter
  jmp cykluss
its_uppercase:  
  inc upper_counter
  jmp cykluss                              

supp:
;DISPLAY TOTAL LOWERCASE.
  mov ah, 9
  mov dx, offset msj1
  int 21h

  call dollars
  mov ax, lower_counter ;PARAMETER FOR NUMBER2STRING.
  call number2string ;RESULT RETURNS IN "STR".

  mov ah, 9
  mov dx, offset str
  int 21h

;DISPLAY TOTAL UPPERCASE.
  mov ah, 9
  mov dx, offset msj2
  int 21h

  call dollars
  mov ax, upper_counter ;PARAMETER FOR NUMBER2STRING.
  call number2string ;RESULT RETURNS IN "STR".

  mov ah, 9
  mov dx, offset str
  int 21h

;FINISH THE PROGRAM.
  mov  ax,4c00h
  int  21h           

;------------------------------------------

;NUMBER TO CONVERT MUST ENTER IN AX.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING.

proc number2string
  mov  bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
  mov  cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:       
  mov  dx, 0 ;NECESSARY TO DIVIDE BY BX.
  div  bx ;DX:AX / 10 = AX:QUOTIENT DX:REMAINDER.
  push dx ;PRESERVE DIGIT EXTRACTED FOR LATER.
  inc  cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
  cmp  ax, 0  ;IF NUMBER IS
  jne  cycle1 ;NOT ZERO, LOOP. 
;NOW RETRIEVE PUSHED DIGITS.
  mov  si, offset str
cycle2:  
  pop  dx        
  add  dl, 48 ;CONVERT DIGIT TO CHARACTER.
  mov  [ si ], dl
  inc  si
  loop cycle2  

  ret
endp  

;------------------------------------------
;FILLS VARIABLE STR WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THESE STRINGS WILL BE DISPLAYED.
proc dollars                 
  mov  si, offset str
  mov  cx, 6
six_dollars:      
  mov  al, '$'
  mov  [ si ], al
  inc  si
  loop six_dollars
  ret
endp  

我们需要做的是检查AL是否介于两个数值范围之间:

enter image description here