How to convert lower case to upper case and vice versa without using subtraction or addition in emu8086
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
Combining two MIPS programs to convert lowercase to uppercase and vice versa
addi $t0, $t0, -32 is faulty.
It should be addi $t1, $t1, -32 .
.data
string: .asciiz "\nThis Is A Test\n"
newline: .asciiz "\n"
.text
main:
la $t0, string # $t0 is pointer to first el of str, loading string
li $v0, 4 # print the original string
la $a0, string
syscall
li $s2, ' '
li $v0, 4
li $t0, 0
loop:
lb $t1, string($t0)
beq $t1, 0, exit
beq $t1, $s2, neither
j caseLower
caseLower:
blt $t1, 'A', caseUpper
bgt $t1, 'Z', caseUpper
addi $t1, $t1, 32
sb $t1, string($t0)
addi $t0, $t0, 1
j loop
caseUpper:
blt $t1, 'a', neither
bgt $t1, 'z', neither
addi $t1, $t1, -32
sb $t1, string($t0)
addi $t0, $t0, 1
j loop
neither:
addi $t0, $t0, 1
j loop
exit:
li $t0, 4
la $a0, string
syscall
li $v0, 10
syscall
Transform uppercase letters to lowercase and vice-versa using single parameter function (C++)
Don't reinvent the wheel. The standard library has functions to identify uppercase and lowercase letter, and to change case. Use them.
char trans(char ch) {
unsigned char uch = ch; // unfortunately, character classification function require unsigned char
if (std::isupper(uch))
return std::tolower(uch);
else
return std::toupper(uch);
}
You might be inclined to change that else
branch to else if (std::islower(uch) return std::toupper(uch); else return uch;
, but that's not necessary; std::toupper
only changes lowercase letters to uppercase, so it won't affect characters that aren't lowercase.
Then, when you call it, just copy the result:
int i = 0;
for ( ; i < strlen(s); ++i)
s2[i] = tran(s[i]);
s2[i] = '\0';
EDIT:
Since there seems to be a requirement to do things the hard way, let's change trans
to match:
void trans(char& ch) {
unsigned char uch = ch; // unfortunately, character classification function require unsigned char
if (std::isupper(uch))
ch = std::tolower(uch);
else
ch = std::toupper(uch);
}
And now, you can just apply it in place:
for (int i = 0; i < strlen(s); ++i)
trans(s[i]);
I called this "the hard way" because with the original version of trans
you can use it directly to modify the original string:
for (int i = 0; i < strlen(s); ++i)
s[i] = trans(s[i]);
and you can use it to copy the string:
for (int i = 0; i < strlen(s); ++i)
s2[i] = trans(s[i]);
// don't forget the terminating nul
With pass by reference, you can only modify in place; copying requires an additional step:
strcpy(s2, s1);
for (int i = 0; i < strlen(s); ++i)
trans(s2[i]);
C++, most efficient way to change uppercase to lowercase and vice versa without condition branching
If your characters are using the ASCII character set you can xor with the value 32 to flip between upper and lower case.
char switchCase(char letter)
{
return letter ^ 32;
}
Related Topics
To_String Is Not a Member of Std, Says G++ (Mingw)
Array[N] VS Array[10] - Initializing Array With Variable VS Numeric Literal
Store Derived Class Objects in Base Class Variables
Pure Virtual Destructor in C++
Unicode Encoding For String Literals in C++11
Do You Use Null or 0 (Zero) For Pointers in C++
What Is the Advantage of Using Forwarding References in Range-Based For Loops
Return Type of ':' (Ternary Conditional Operator)
How to Determine If a String Is a Number With C++
How to List-Initialize a Vector of Move-Only Type
Static Variables Initialisation Order
Is It Good Practice to Null a Pointer After Deleting It
What Is an 'Undeclared Identifier' Error and How to Fix It