I am writing an assembly program that capitalizes the first letter of each word in the sentence I input.
My problem is that it doesn't capitalize the first letter of the words. What's wrong with my code?
Below is my code
.model small
.stack 100h
.data
prompt1 db "Input String: $"
prompt2 db "Output String: $"
InputString db 21,?,21 dup("$")
newline db 10,13,"$"
.code
start:
mov ax, @data
mov ds, ax
; Getting input string
mov ah,09h
lea dx, prompt1
int 21h
lea si, InputString
mov ah, 0Ah
mov dx, si
int 21h
nextline:
mov ah, 09h
lea dx, newline
int 21h
loop1:
mov cl, [si+1]
mov ch,0
add si, cx
inc si
dec cx
cmp cx, 0
je exit
jmp checkspace
checkspace:
cmp si, " "
inc si
je checkletter
checkletter:
cmp si, "a"
jae checkletter2
checkletter2:
cmp si, "z"
jbe capital
capital:
mov ah, [si]
xor ah, 00100000b
mov [si], ah
jmp loop1
exit:
mov ah,09h
lea dx, prompt2
int 21h
mov ah, 09h
mov dx, offset InputString+2
int 21h
mov ah, 4ch
int 21h
end start
Below is the updated part of my code. It can now only capitalize the first letter of the word. I don't know if the problem is with the loop. Please help me figure out which part of my code is wrong. I'm so sorry I don't know how to use a debugger for checking. Thank you.
mov cl, [si+1]
mov ch,0
add si,2
jmp checkletter
loop1:
inc si
dec cx
cmp cx, 0
je exit
cmp si, " "
je checkletter3
jmp loop1
checkletter:
cmp si, 41h
jae checkletter2
checkletter2:
cmp si, 5Ah
jbe capital
checkletter3:
inc si
dec cx
jmp checkletter
capital:
mov ah, [si]
xor ah, 00100000b
mov [si], ah
jmp loop1
cmp si, " " cmp si, "a" cmp si, "z" cmp si, 41h cmp si, 5Ah
All of the above are comparing the address in SI
with an immediate value. They are not comparing the byte that can be found at the address that SI
is pointing to with the immediate! You need to dereference it.
cmp byte [si], " "
cmp byte [si], "a"
cmp byte [si], "z"
cmp byte [si], 41h
cmp byte [si], 5Ah
To solve the task of capitalizing just the first letter of each word
It look like this:
mov cl, [si+1]
test cl, cl ;Exit if the input was empty!!!
jz Exit
add si, 2 ;Point at first byte
SkipSpace:
mov al, [si]
cmp al, " "
jne FirstCharacter
inc si ;(*)
dec cl
jz Exit
jmp SkipSpace
FirstCharacter:
cmp al, "a"
jb SkipRemainingCharacters
cmp al, "z"
ja SkipRemainingCharacters
sub al, 32 ;Capitalize
mov [si], al ; and write back in string
SkipRemainingCharacters:
inc si
dec cl
jz Exit
mov al, [si]
cmp al, " " ;If not space then it's part of same word
jne SkipRemainingCharacters
jmp SkipSpace ;This could just as easily jump to (*)
Exit: