I'm writing a program in .asm which prompts the user to enter a sentence. I have no problems with this but one requirement of the program is to change the format of the sentence by replacing all the spaces (" ") with underscore characters ("_"). How do I go about singling out the spaces and the changing them?
You would have to load the first byte from your string and check to see if it is a space. If it is, then replace that byte with '_'. Otherwise, just check the next byte. You'd repeat this in a loop until you find the end-of-string character.
Which assembly syntax are you using? If you don't know, then are you compiling on DOS, Linux or what?
I'm compiling on DOS with TASM? Would I be correct with something along the lines like this or am I getting too complicated? The array prompts the user to enter up a maximum of 60 characters, actlen holds the actual size of the array.
lea bx, array mov cx, actlen mov ax, ' ' again: cmp ax, [bx] inc bx dec cx jne again je multiple multiple: mov [bx], '_' loop again
That's nice code, but I think it'll replace the character after the space with an underscore; you increment BX before you store the underscore. Also, you're comparing words (
cmp AX, [bx]), not bytes, so your code will never find any spaces.
To simplify your code, you might want to make use of the
loop instructions. See http://faydoc.tripod.com/cpu/lodsb.htm and http://faydoc.tripod.com/cpu/loop.htm for details. Basically,
lodsb will load a byte from the segment:offset pair
DS:SI into al and increment SI all in one.
loop will decrement CX and jump to the specified label if
CX != 0. You could also try storing a null character just after the string to denote the end of the string. While it uses up one extra byte in memory, it makes code much tidier and smaller, for example:
array db "imaginary input",0 mov si, array .checkloop: lodsb ; Load next byte into AL and increment SI cmp al, 0 ; End of string? jz .quit ; If so, quit the loop cmp al, ' ' ; Is the character a space? jnz .checkloop ; If not, load the next byte dec si ; Move back to the address of the space mov al, '_' ; Put character to store in AL stosb ; Store the underscore over the space jmp .checkloop ; Loop .quit: ; do something else...
You could use
lodsb like this:
mov si, array mov cx, actlen .checkloop: lodsb ; Load next byte into AL and increment SI cmp al, ' ' ; Is the character a space? jz .replace ; Replace it if it is loop .checkloop ; Loop until end of string jmp .quit ; Jump over our .replace function .replace: dec si ; Move back to the address of the space mov al, '_' ; Put character to store in AL stosb ; Store the underscore over the space jmp .checkloop .quit: ; do something else...
Whatever you prefer, I just find that using null-terminated tends to make code more linear, ie. not jumping all over the place. It's up to you.
Yeah I see your point, the code becomes much easier to follow and to understand with your way rather than have multiple jumps going up and down the lines of code; especially if I was to come back and make changes or improvements. Thanks for your help on the matter.
No problem! Please mark the thread as being solved if your question's answered.