I was reading HLA's book and found 2 functions that convert chars to UPPERCASE:
program charInputDemo2;
#include( "stdlib.hhf" )
static
c:char;
begin charInputDemo2;
stdout.put( "Enter a character: " );
stdin.get(c);
if( c >= 'a' ) then
if( c <= 'z' ) then
and( $5f, c );
endif;
endif;
stdout.put
(
"The character you entered, possibly ", nl,
"converted to upper case, was '",
c,
"'", nl
);
end charInputDemo2;
and LOWERCASE:
mov( StringAddress, esi ); // Load string address into ESI.
mov( esi, edi ); // Also point EDI here.
mov( (type str.strrec [esi].length, ecx );
repeat
lodsb(); // Get the next character in the string.
if( al in 'A'..'Z' ) then
or( $20, al ); // Convert upper case character to lower case.
endif;
stosb(); // Store converted character back into string.
dec( ecx );
until( @z ); // Zero flag is set when ECX decrements to zero.
and( $5f, c ); (5Fh) is: _
or( $20, al ); (20h) is: (space)
But i dont understand WHY 5Fh in U.CASE and 20h in L.CASE.
Why not 6h and 25h (just example) ??
Can somebody explain whats going on? Book doesnt say anything about this. And thats :tdown
Something coz of ASCII ?
Yes, in ASCII the difference between uppercase "A"=41h and lowercase "a"=61h
So:
41h or 20h = 61h --> to lowercase
61h and 5fh = 41h --> to uppercase
Ok, i understand: 41 in HEX is 'A' and 61 in HEX is 'a'
But what is the 20h and 5fh? From where? By some calculation?
I was looking ASCII table, i dont see any connection between for example: 20h and 'A' & 5fh and 'a'
Whats the trick? Why 20h can be 'A' and 5Fh can be 'a' ?
Maybe im stupid but i would like to know.
For AND and OR?
dunno.
Very strange...
20h and 5Fh are constants from calculation. 20H is not "A" nor is 5Fh 'a', they are simply immediate operands used to calculate the value of a character in the opposite case.
"A" OR 20h = "a"
"a" AND 5Fh = "A"
QuoteBut what is the 20h and 5fh
20h is 32 decimal, which is being ORed into the [A..Z] value therby making it in range [a..z]
5fh is 01011111 (binary :bg) which when ANDed will "chop off" the 32 decimal from any character between [a..z] making it [A..Z]
Hope that helps. If any more problems, write the hex, decimal and binary values of the numbers concerned at you will "see the light" :wink
BytePtr,
60h - 40h = 20h
That is where the 20h comes from.
hth,
Paul
Thanks alot for answers. Now i understand, a bit strange way by author to do this conversion (for me atleast).
shantanu_gadgil BIN, HEX, DEC conversion is easy for me. I know how to convert them between each other (numeric systems) and do all possible arithmetics with them. Very easy, coz ive learned this already :thumbu.
But i must learn more about logical operators and how they act with bits. Its important like you see from my problem.
Boolean algebra, nice.
Thanks all :U
BytePtr,
So I guess the easiest way of explaining it is if you want to convert from upper to lower, add 32 (20h). To convert from lower to upper, subtract 32 (20h).
Take a peek at szlower.asm and szupper in the m32lib directory in masm32.
Paul.
Thanks PBrennick for algo.
I should play with the ASCII's and logical op's more. Will try to write my own uppercase and lowercase functions now in asm, good way to learn i guess.
Simple test in Delphi:
edit1.Text:=chr(($41) or ord(chr(($20))));
edit2.Text:=chr(ord($41)+($20));
Both result is: a
Correct, i guess :P
Quote from: PBrennick on March 12, 2006, 06:51:21 PM
the easiest way of explaining it is if you want to convert from upper to lower, add 32 (20h). To convert from lower to upper, subtract 32 (20h).
The second easiest way of explaining is toggling bit 5 (00100000b or 20h) will toggle the case. So any letter that has bit 5 set will be lowercase, while any letter that has bit 5 cleared will be uppercase (of course there are some characters that aren't letters that have this bit set/cleared, hence the > 'a' < 'z' test)
Cheers,
Zooba :U
:U