I am trying to write a trivial toUpper procedure in MASM for ASCII only. It works, however, whenever it encounters a whitespace character, it wont continue changing the case of that character and the ones following it. I can't figure out the reason why this is happening. So what I did is put a conditional statement to test if a character is a space ' ' (32) and thus jump beyond it. Is this enough or should I test for any value that is not between 97 and 122 also?
; EDX - INPUT - The offset to the BYTE Array
; ECX - INPUT - The Size of the BYTE Array
; EDX - OUTPUT- The offset to the new BYTE Array toUpper PROC
PUSH ECX ; we will modify this so push it to the stack
DEC ECX ; we don't want the null terminating char
loopMe:
MOV AL, [EDX] ; otherwise move what the EDX points to to AL
CMP AL, 32
JNE goodChar
INC EDX ; increment the pointer by one byte since this is a space
loop loopMe ; go to the next char
goodChar:
AND AL , 11011111b ; make AL capital
MOV [EDX], AL
INC EDX ; increment the pointer by one byte
LOOP loopMe
done:
POP ECX ; return it back to its original value
RET toUpper ENDP
You have a problem after the first LOOP instruction:
PUSH ECX
DEC ECX
loopMe:
MOV AL, [EDX]
CMP AL, 32
JNE goodChar
INC EDX
LOOP loopMe
<--- what happens here?
goodChar:
AND AL , 11011111b
MOV [EDX], AL
INC EDX
LOOP loopMe
done:
POP ECX
RET toUpper
There are two solutions here, either jump to the second LOOP
or jump to the done:
label after the first loop. Also, you should really only apply the upper "trick" to 'a-z', which means the CMP AL,...
would test against 'a', if smaller, jump to the loop, then test again against 'z', if larger, jump to the loop.
PUSH ECX
DEC ECX
loopMe:
MOV AL, [EDX]
CMP AL, 'a'
JL next
CMP AL, 'z'
JG next
AND AL , 11011111b
MOV [EDX], AL
next:
INC EDX
LOOP loopMe
done:
POP ECX
RET toUpper