I been having trouble. I want to change my sentence to lower case except for the first letter in each word. I been told to campare it to a space (20h) but I don't know how to do it. Help anyone?? Thanks in advance.
.data
sentence BYTE "CHANGE TO LOWER CASE!!"
sentence1 BYTE 30 DUP (?)
.code
main PROC
;this prints the original sentence
mov edx, OFFSET sentence
call WriteString
call Crlf
;Print sentence in Lowercase letters
mov ecx, LENGTHOF sentence1
mov esi, 0
mov al,0
L1:
mov al, sentence[esi]
cmp esi,0
je NoUpperCase ;for the first symbol
cmp al,41h
jl NoUpperCase ; if less then 'A'
cmp al,5ah
jg NoUpperCase ;if greater then 'Z'
add al,32d
NoUpperCase:
mov sentence[esi], al
inc esi
;mov edx, OFFSET sentence
loop L1
call WriteString
call Crlf
exit
main ENDP
END main
To determine if the character is above 'Z', compare it to the character code for 'Z':
cmp al,'Z'
ja NoUpperCase
Pro32,
Here is a procedure that is flag driven:
If flag = 3 then invert case, if upper convert selected text to lower or if lower convert selected text to upper.
If flag = 2 then convert selected text to upper.
If flag = 1 then convert selected text to lower.
ChangeCase proc
;---------------------------------------
inv SendMessage, hREdit, EM_EXGETSEL, 0, offset cr ; Get start and ending positions of highlighted text
mov eax, cr.cpMax ; Get end position
sub eax, cr.cpMin ; Minus the start position
.if eax < 255 ; If in range...
inv SendMessage, hREdit, EM_GETSELTEXT, 0, addr szFlipCase ; Get selected text
.endif ; End of conditional
push edi ; Register preservation
mov edi, Offset szFlipCase ; Pointer to text selection storage buffer
J001: mov al, [edi] ; Get a character
.if Flag == 3 ; Invert selected text
.if al >= 'A' && al <= 'Z' ; If upper case...
or byte ptr [edi], 20h ; Convert it to lower case
.elseif al >= 'a' && al <= 'z' ; If lower case...
and byte ptr [edi], 5fh ; Convert it to upper case
.endif ; End of conditional
.elseif Flag == 2 ; Convert selected text to upper case
.if al >= 'a' && al <= 'z' ; If lower case...
and byte ptr [edi], 5fh ; Convert it to upper case
.endif ; End of conditional
.elseif Flag == 1 ; Convert selected text to lower
.if al >= 'A' && al <= 'Z' ; If upper case...
or byte ptr [edi], 20h ; Convert it to lower case
.endif ; End of conditional
.endif ; End of conditional
inc edi ; Update the buffer pointer
or al, al ; Done?
jne J001 ; Continue until ASCIIZ is reached
pop edi ; Restore the register
; Put back the reconditioned text
inv SendMessage, hREdit, EM_REPLACESEL, TRUE, addr szFlipCase
ret ; Return to caller
;---------------------------------------
ChangeCase endp
Paul
If size is not a factor you might think about using a table and XLATB. It is fairly fast once the table is in the data cache...
align 16
lcase:
db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
db 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
db 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47
db 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
db 64, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111
db 112,113,114,115,116,117,118,119,120,121,122, 91, 92, 93, 94, 95
db 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111
db 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127
db 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143
db 144,145,146,147,148,149,150,151,152,153,154,155,156,156,158,159
db 160,161,162,163,164,165,166,167,168,169,170,171,172,173,173,175
db 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191
db 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207
db 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223
db 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239
db 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
lszCase FRAME pString
uses ebx,esi,edi
mov ebx,offset lcase
mov edi,[pString]
mov esi,[pString]
xor ecx,ecx
:
mov al,[esi+ecx]
xlatb
mov [edi+ecx],al
inc ecx
or al,al
jnz <
:
mov eax,edi
RET
ENDF
For upper case use the same routine but change the table...
align 16
ucase:
db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
db 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
db 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47
db 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
db 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79
db 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95
db 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79
db 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127
db 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143
db 144,145,146,147,148,149,150,151,152,153,154,155,156,156,158,159
db 160,161,162,163,164,165,166,167,168,169,170,171,172,173,173,175
db 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191
db 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207
db 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223
db 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239
db 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
Nowadays with the extreme disk sizes we get to play with, size is no longer much of an issue. Tables are pretty fast, too, Donkey?
Paul
I think they are a little slow generally but I would imagine that they must be faster than a large grouping of compares and jumps. I usually use the table method as in reality there is never too much data to translate, a few hundred chars at the most. I would think that the programmatic method would be faster on small strings, I have never really tested it.
Pro32
To answer your question, add the following instructions just before you change from upper to lower case:
cmp byte ptr[esi-1]," " ;checks if previous character was a space
jz NoUpperCase ;don't change the 1st letter of a word
Raymond
Quote from: Pro32 on February 19, 2005, 11:53:17 PM
I been having trouble. I want to change my sentence to lower case except for the first letter in each word. I been told to campare it to a space (20h) but I don't know how to do it. Help anyone?? Thanks in advance.
Actually, the more difficult problem is figuring out what is the first character of each word. Different people have different ideas about what constitutes a "word". So you should specify that first. After you can pick out individual words from a string, then the lower case conversion is easy.
BTW, do you *ignore* the first character of each word, or do you convert it to upper case?
Cheers,
Randy Hyde
Quote from: raymond on February 20, 2005, 04:39:00 AM
Pro32
To answer your question, add the following instructions just before you change from upper to lower case:
cmp byte ptr[esi-1]," " ;checks if previous character was a space
jz NoUpperCase ;don't change the 1st letter of a word
Raymond
I've tried adding those lines but it crashes my program. Where exactly do I put it...and what goes in between the quotation marks... I think I have an idea of where your going so this helps a lot. Thanks
Quote from: Randall Hyde on February 20, 2005, 05:36:20 AM
Quote from: Pro32 on February 19, 2005, 11:53:17 PM
I been having trouble. I want to change my sentence to lower case except for the first letter in each word. I been told to campare it to a space (20h) but I don't know how to do it. Help anyone?? Thanks in advance.
Actually, the more difficult problem is figuring out what is the first character of each word. Different people have different ideas about what constitutes a "word". So you should specify that first. After you can pick out individual words from a string, then the lower case conversion is easy.
BTW, do you *ignore* the first character of each word, or do you convert it to upper case?
Cheers,
Randy Hyde
I want to ignore it because its already in Upper Case.
QuoteI've tried adding those lines but it crashes my program. Where exactly do I put it...and what goes in between the quotation marks... I think I have an idea of where your going so this helps a lot. Thanks
You can use characters between quotation marks and they will be interpreted by the assembler as their ASCII code. MichaelW provided you with an example:
cmp al,"Z" is the same as
cmp al,5ah.
And " " is the same as using 20h.
Using such technique makes the code easier to visualize and you don't need to refer to an ASCII conversion table for all the characters.
If you have not changed the code you originally posted, the instructions I suggested would go
immediately before the
add al,32d. And I can't see why the program should crash unless you did change that original code.
Raymond
P.S. You should also start practicing the use of null-terminated strings. Those are a necessity if you intend to use a lot of the Windows API functions. It's also a lot easier to detect the end of a string instead of relying on the count of characters returned by LENGTHOF and then using either a register or memory to keep track of it.
Quote from: raymond on February 20, 2005, 05:36:44 PM
QuoteI've tried adding those lines but it crashes my program. Where exactly do I put it...and what goes in between the quotation marks... I think I have an idea of where your going so this helps a lot. Thanks
You can use characters between quotation marks and they will be interpreted by the assembler as their ASCII code. MichaelW provided you with an example:
cmp al,"Z" is the same as cmp al,5ah.
And " " is the same as using 20h.
Using such technique makes the code easier to visualize and you don't need to refer to an ASCII conversion table for all the characters.
If you have not changed the code you originally posted, the instructions I suggested would go immediately before the add al,32d. And I can't see why the program should crash unless you did change that original code.
Raymond
P.S. You should also start practicing the use of null-terminated strings. Those are a necessity if you intend to use a lot of the Windows API functions. It's also a lot easier to detect the end of a string instead of relying on the count of characters returned by LENGTHOF and then using either a register or memory to keep track of it.
It works! I just had to tweek your code a bit. I'm using registry to store characters because I'm new to this language. I hope I'll get better with the help of this community. Thanks a bunch.