You could also XOR the character with 32. It's much safer to use in this case instead of SUB.
CODE
;Assuming the the character is stored in AL
xor AL , 20h
This can also convert uppercase into lowercase.
Now, take a look at this fragment:
CODE
mov cl,ERR
call getch ;reads the lowercase letter or % symbol
cmp cl,al
Although this may not create a problem in this case (since you have defined the getch code yourself), there is a chance that the called function is modifying the CL register without the PUSH CX/POP CX instruction pair.
Hence a wiser step that you could take would be:
CODE
call getch ;reads the lowercase letter or % symbol
mov cl,ERR
cmp cl,al
CODE
call getch
...
...
...
getch:
mov ah, 01h;Display DOS func code
int 21h;Call DOS
putch:
mov dl, bl ;displays the character
mov ah, 2h
int 21h
end:
mov al,0 ;Exits the program - _Exit equivelant
mov ah,4ch
int 21h
Since you're using the CALL instruction, control won't be passed onto the next statement (after call getch) until a RETN instruction is encountered. This could be the cause of your crash.
Either use JMP getch along with GOTOs planted at the end of getch and putch blocks, or place a RETN instruction at the end of getch/putch.