In assembly, lower case to upper case or upper case to lower case conversion is easy. if input is lower case then adding 32d will give the upper case letter Or if input is upper case, then subtracting 32d will give lower case letter. But I want to do this conversion without using subtraction or addition.
This is an interesting observation that if you look into ascii a~z
's binary value, you'll see that all of them have the 6th bit set to 1
. and all ascii A~Z
's 6th bit is set to 0
. And remaing all bits are same. Check it out:
a = 01100001 z = 01111010
A = 01000001 Z = 01011010
^ ^
Now, 6th bit binary value is 32 (00100000
) . So, if we can do xor
operation with lower case or upper case letter then it will convert. Easy thing to remember: 32d
is related to upper to lower Or lower to upper. Here is the demo code:
; Here at first, @ indicating start of label and $ indicating start of procedure.
; If multiple label and procedure is present in assembly code.
; Then distinguishing label & procedure can be done easily.
; It's just my own way of coding. You may ignore this style.
.model small ; declaring this code will be consists of one data segment and one code segment
.stack 100h ; stack is initializeed to offset address at 100h
.data ; starting of Data segment
n_line db 0ah,0dh,"$" ; for new line
input_msg db "Input",20h,": $" ; 20h = 32d = ascii 'space'
output_msg db 0ah,0dh,"Output: $"
stop_msg db "Press 'esc' to Stop this Programme.",0ah,0dh,"$"
end_msg db 0ah,0dh,"Proramme Terminated. $"
warning_msg db 0ah,0dh,"Input is not a letter. Try agian.",0ah,0dh,"$"
.code ; starting of Code segment
main proc
mov ax,@data ; copying starting address of data segment into ax register
mov ds,ax ; by copying ax into ds we are initializing data segment
lea dx,stop_msg
mov ah,9
int 21h
@input:
mov cx,0
lea dx,input_msg
mov ah,9
int 21h
mov ah,1 ; taking single input charachter
int 21h
cmp al,27d ; cheking if it input is 'esc' or not
je @terminate
call $check_constraints ; procedure calling
cmp cx,1 ; cheking flag value
je @input
xor bx,bx ; XOR with self will always retun of all zero bit (means clearing a register)
mov bl,al
xor bl,32d ; Here is the bit trick
@output:
lea dx,output_msg
mov ah,9
int 21h
mov dl,bl ; output char was stored in bl
mov ah,2
int 21h
lea dx,n_line ; new line for next input
mov ah,9
int 21h
jmp @input
@terminate:
lea dx,end_msg
mov ah,9
int 21h
mov ah,4ch ; terminate program
int 21h
main endp ; ending of main procedure
$check_constraints proc
; if( (input<= 122d && input <= 97d) || (input<=90d && input <= 65d)) Then Proceed; otherwise Warning;
@first_if:
cmp al,122d ; or cmp al,'z'
jg @warning
cmp al,97d ; or cmp al,'a'
jge @setFlag
@second_if:
cmp al,90d ; or cmp al,'Z'
jg @warning
cmp al,65d ; or cmp al,'A'
jl @warning
@setFlag:
mov cx,0 ; i'm considering cx register as a flag
jmp @end_function
@warning:
mov cx,1 ; i'm considering cx register as a flag
lea dx,warning_msg
mov ah,9
int 21h
@end_function:
ret
$check_constraints endp
end main ; ending of code segment