Split string in assembly

I'm using a code for split a string with a delimiter, but it save me the "right side" and I need the "left side" of the word.

For example, if the input is 15,20,x, then the outputs should be:

15
20
x

But it show me:

15,20,x
20,x
x

This is the code that I'm using

split:
    mov     esi,edi
    mov     ecx, 0 
    not     ecx    
    mov     al, ','
    cld         
    repne     scasb
    not     ecx
    lea     eax, [ecx-1]

    ;push     eax
    mov     eax, edi
    call     println        ;Here is where I want to print the "left side"
    ;pop     eax

    xchg     esi, edi

    mov     eax, esi
    call     length

    mov     edi, esi
    mov     ecx, eax
    cmp     ecx, 1
    je         fin
    jg         split
    ret
fin:
    ret

Upvotes: 1

Views: 4219

Answers (1)

vitsoft
vitsoft

Reputation: 5775

After repne scasb the contents of ECX has changed from -1 to -4, you need to NOT ECX and then DEC ECX to obtain ECX=2 (size of the member "15"). Then println ECX bytes of the text at ESI and repeat split: There is a rub: as the last member "x" is not terminated with comma, repne scasb will crash. You should limit ECX to the total size of input text prior to scan. I tried this variant with EuroAssembler:

; Assembled on Ubuntu with
; wine euroasm.exe split.asm
; Linked with
; ld split.obj -o split -e Main -m elf_i386
; Run with
; ./split
       EUROASM
split  PROGRAM Format=COFF, Entry=Main:
        INCLUDE linapi.htm,cpuext32.htm ; Library which defines StdInput,StdOutput.
[.text]
Main:   StdOutput ="Enter comma-separated members: "
        StdInput  aString    ; Read aString from console, return number of bytes in ECX.
        MOV EDI,aString      ; Pointer to the beginning of text.
        LEA EBX,[EDI+ECX]    ; Pointer to the end of text.
split:  MOV ESI,EDI          ; Position of the 1st byte.
        MOV ECX,EBX
        SUB ECX,EDI          ; How many bytes is left in unparsed substring.
        JNA fin:
        MOV AL,','
        REPNE SCASB
        MOV ECX,EDI
        DEC ECX              ; Omit the delimiter.
        SUB ECX,ESI
        StdOutput ESI, Size=ECX, Eol=Yes
        JMP split:
fin:    TerminateProgram
[.bss]
aString DB 256 * BYTE
       ENDPROGRAM split

And it worked well:

./split
Enter comma-separated members: 15,20,x
15
20
x

Upvotes: 1

Related Questions