The problem is to remove first occurring space from string in assembly 8086. I have written a test code, which apparently is not working. My idea is the following: set both di and si to be equal to the same string. keep di the same as long as no character is found. as soon as a character is found start setting di to the values that come afterwards. In this case "sometext mytext" should stay the same after 8 iterations and then "sometext mytext" -> "sometextmmytext" -> "sometextmyytext" -> ... -> "sometextmytexxt" -> "sometextmytext$$"
then last $ can be removed by hand.
Now, I am using the flag CF to know if the space has been found or not. But strangely, CF becomes set sooner than it should and when I try to debug the code I see that di is changing when it still shouldn't. Am I debugging wrongly or is something really wrong regarding my code that depends on CF? Also, if I run the code that I have posted it will say "not found" which is also weird. This makes me thing that the logic of my code is completely flawed yet I don't understand why. Could you explain me what is wrong and maybe post or hint to a better solution? I have also tried to solve using lods/stos but I failed that too. Thanks in advance.
P.S. as you can guess I'm new to assembly. maybe in some places my code is uselessly long when I could keep it shorter (I didn't focus on this task that much as I'm still trying to get this code to work). Also I might be righting inefficient code (even though my priority now is solving the problem itself). But, any advise is welcome.
EDIT: I have hardcoded the length of the string, I know that it can be retrieved from its first byte, but I was trying to solve for this sample at first.
.model small
.stack 256
.data
a db "sometext mytext$"
b db 10,"found$"
c db 10,"not found$"
.code
entrr proc
push ax dx
mov ah,2
mov dl,10
int 21h
mov dl,13
int 21h
pop dx ax
ret
entrr endp
PRINT MACRO x
push ax
push dx
mov ah,09
mov dx,x
int 21h
pop dx
pop ax
ENDM
START:
mov ax,@data
mov ds,ax
mov bl, ' '
mov cl, '$'
xor ax,ax
xor cx,cx
clc
lea si, a
lea di, a
compare:
cmp cx, 15
je endstr
jnc check_for_space
jc setdi
inc cx
jmp compare
check_for_space:
cmp [si 1], bl
je found
inc di
inc si
inc cx
jmp compare
setdi:
mov bl,[si 1]
mov [di],bl
inc di
inc cx
jmp compare
found:
push di
lea di,b
PRINT di
pop di
stc
inc si
inc cx
jmp compare
endstr:
jnc notfound
jmp done
notfound:
lea si,c
PRINT si
jmp finish
done:
; print di
finish:
mov ax,4c00h
int 21h
END START
CodePudding user response:
compare: cmp cx, 15 je endstr jnc check_for_space jc setdi
The culpritt is that cmp cx, 15
instruction at the top of the loop. cmp
modifies the flags:
- When
CX
is from 0 to 14, the code will obviously not jump to endstr, but because the carry flag will be set (the value in the register is below 15), the code will jump to setdi (something you don't want). - When
CX
finally becomes 15, the code will indeed jump to endstr, but because equality also entails that the carry flag will be clear, the code at endstr will jump to notfound
Next code should give you an idea:
mov bl, ' '
lea si, a ; Address of the string
mov di, si
mov cx, 15 ; Length of the string
Again:
cmp [si], bl
je IsSpace
inc di
inc si
dec cx
jnz Again
NotFound:
...
jmp Quit
Copy:
mov al, [si]
mov [di], al
inc di
IsSpace:
inc si
dec cx
jnz Copy
Found:
...
Quit:
...
We don't jump to the top of the Copy loop because it could be that the space character was found at the last position in the string, fact that we recognize by the dec cx
turning zero.