1

These codes convert uppercase letters ("letters only") to lowercase letters and lowercase letters to uppercase. My question is that I want to print them as well and keep them unchanged, if any (non-verbal symbols and actors). With the cmp and ... commands that you see in the program

data segment
    ; add your data here!
    ar db "haP!y bi3Rthday$"
ends

stack segment
    dw   128  dup(0)
ends

code segment
start:
; set segment registers:
    mov ax, data
    mov ds, ax
    mov es, ax

    ; add your code here
   mov si,0
   mov ah,01
   int 21h
   cmp al,"c"
   je c
   cmp al,"l"
   je l
   jmp exit
 c:cmp ar[si],"$"
   je exit
   cmp ar[si],96
   jl c2
   sub ar[si],32
 c2:inc si
    jmp c
    
 l: cmp ar[si],"$"
    je exit
    cmp ar[si],96
    jg l2
    add ar[si],32
 l2:inc si
    jmp l
 
 exit:lea dx,ar
      mov ah,09
      int 21h
    
    mov ax, 4c00h ; exit to operating system.
    int 21h    
ends

end start ; set entry point and stop the assembler.
Tiago
  • 15
  • 6
  • 1
    This would be a lot easier to follow if you'd use more descriptive names for your labels, like `check_upper_case` instead of `c2` or whatever. Comments are a good idea too. – Nate Eldredge Jun 13 '21 at 16:01

1 Answers1

2

You need to restrict the ranges for the uppercase and lowercase characters by specifying a lower limit and a higher limit, not just the one value (96) that your current code uses.

Uppercase characters [A,Z] are in [65,90]
Lowercase characters [a,z] are in [97,122]

The nice thing of course is that you don't actually need to write these numbers in your code. You can just write the relevant characters and the assembler will substitute them for you:

Up: cmp ar[si], "$"
    je  exit
    cmp ar[si], "a"
    jb  Up1
    cmp ar[si], "z"
    ja  Up1
    sub ar[si], 32    ; Make uppercase
Up1:inc si
    jmp Up
    
Lo: cmp ar[si], "$"
    je  exit
    cmp ar[si], "A"
    jb  Lo1
    cmp ar[si], "Z"
    ja  Lo1
    add ar[si], 32    ; Make lowercase
Lo1:inc si
    jmp Lo
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • 2
    Elegant way how to change the case of letters in the range 'a'..'z' or 'A'..'Z' is to **XOR** them with 00100000b = **32**. – vitsoft Jun 13 '21 at 16:08
  • you don't need 2 comparisons like this because `if (ar >= 'a' && ar <= 'z')` [can be converted to `if ((unsigned)(ar - 'a') <= ('z' - 'a'))`](https://stackoverflow.com/a/17095534/995714) and in fact modern compilers do know that optimization – phuclv Jun 15 '21 at 02:11