News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Trimming spaces and tabs inside a string

Started by Vortex, June 17, 2024, 07:52:59 PM

Previous topic - Next topic

NoCforMe

Nope, I missed that.
Modified my code above to return the trimmed length.
Happy?
Assembly language programming should be fun. That's why I do it.


TimoVJL

May the source be with you

zedd151

Quote from: TimoVJL on June 18, 2024, 09:06:29 PMAlso is an as a linux as or windows as.exe ?  :tongue:
You do have a sense of humor.   :greenclp:
No, not using "as" as assembler here.  :tongue:  therefore I am not assembling said clam.  :toothy:

Vortex

Another version :

- Removed conditional setnz instructions.
- No need of ebx.

include     RemoveSpaces.inc

.data

mystr       db '    This    Is   A       Test String.',0
msg         db '%s',13,10,'Lenght of string = %u',0

.data?

buffer      db 256 dup(?)
buffer2     db 32 dup(?)

.code

RemoveSpaces PROC str1:DWORD,buff:DWORD

    mov     ecx,str1
    mov     edx,buff
@@:
    movzx   eax,BYTE PTR [ecx]
    mov     BYTE PTR [edx],al
    add     ecx,1

    xor     al,32
    mov     ah,al
    xor     al,41
    and     ah,al
    add     ah,0FFh
    adc     edx,0

    cmp     al,9
    jne     @b

finish:

    mov     eax,edx
    sub     eax,buff
    ret

RemoveSpaces ENDP

start:

    invoke  RemoveSpaces,ADDR mystr,ADDR buffer

    invoke  wsprintf,ADDR buffer2,\
            ADDR msg,ADDR buffer,eax

    invoke  StdOut,ADDR buffer2
    invoke  ExitProcess,0

END start


NoCforMe

So can you explain to us how this works?
    xor    al,32
    mov    ah,al
    xor    al,41
    and    ah,al
    add    ah,0FFh
    adc    edx,0

    cmp    al,9
    jne    @b
It may be obvious to you, but it sure isn't to me.
Assembly language programming should be fun. That's why I do it.

Vortex

Hi NoCforMe,

    xor    al,32 ; XORing al with 32 has two results : zero or another value
    mov    ah,al ; copy al to ah

    xor    al,41 ; To get back the original value of al, we can do again xor al,32. This would be followed by
                   xor al,9. Combined XOR operations removes the extra second xor al,32  : 32 xor 9 = 41
                   xor ( xor al,32 ) , 9 = xor al,41
                   XORing al with 41 has two results : zero or another value

    and    ah,al ; This and operation will reduce the number of results ( ah and al ) to one :
                   The possible combinations :
                   ah=0 , al=non-zero , and ah,al -> 0
                   ah=non-zero , al=0 , and ah,al -> 0
                   ah=non-zero , al=non-zero , and ah,al -> non-zero

    add    ah,0FFh ; if (and ah,al) = 0 => 0+255 = 255 = > the carry flag is zero.
                     if (and ah,al) = non-zero => <non-zero value> + 255 will cause an overflow setting the
                     carry flag to 1

    adc    edx,0   ; Carry flag = 0 => the original value of al was 32 or 9 and they should be bypassed with
                     the condition carry flag=0 : edx + 0 + carry flag 0 = edx
                   ; Carry flag = 1 => the original value of al was not 32 or 9 and this character should be
                     preserved in the buffer pointed by edx : edx + 0 + carry flag 1 = edx+1
    cmp    al,9    ; After the previous operations xor al,32 and xor al,41, the NULL terminator is converted to
                     ASCII 9
    jne    @b      ; If al!=9 the go to return back to the beginning of the loop.

NoCforMe

Assembly language programming should be fun. That's why I do it.

interfind

Is there a Problem in RemoveSpaces
with the char's ! ( ) in the result string?

Vortex

Hello,

Thanks for your feedback, you are right. The previous version seems to work fine, tested with the exclamation symbol !

https://masm32.com/board/index.php?msg=131754

RemoveSpaces PROC uses ebx str1:DWORD,buff:DWORD

    mov     ecx,str1
    mov     edx,buff
    xor     ebx,ebx
@@:
    movzx   eax,BYTE PTR [ecx]
    mov     BYTE PTR [edx],al
    add     ecx,1

    xor     al,32
    setnz   ah
    xor     al,41
    setnz   bl
    and     bl,ah
    add     edx,ebx

    cmp     al,9
    jnz     @b

finish:

    mov     eax,edx
    sub     eax,1
    sub     eax,buff
    ret

RemoveSpaces ENDP

NoCforMe

@Vortex: questions for you:
1. WHY?
I get that your routine is very, very clever, but is that the reason you coded it? To prove how tricky you can be? I still can't really see the advantage over my admittedly somewhat dumbass (meaning straightforward) approach to the problem. Maybe your code is faster, I'll grant that, but in most cases, does that really matter?

2. HOW?
How did you come up with this way of stripping characters? All that XORing and stuff; did you come up with this on your own? or did you see this code somewhere?
If you came up with it on your own, how did you work this out?

Curious minds want to know.
Assembly language programming should be fun. That's why I do it.