2

What loop should I write If I want to skip all spaces at the beginning of the string and start to do something with the string when my code reaches the first symbol of the string. If I have a string like

a='        s o m e word'

the code should start when 's' is reached. It should be some kind of loop but I still don't know how to write it correctly.

My try:

    mov  si, offset buff+2 ;buffer

    mov ah, [si]
    
    loop_skip_space:
        cmp ah,20h ;chech if ah is space            
        jnz increase ;if yes increase si 
        jmp done ;if no end of loop
        increase:
                          
            inc si 

    loop loop_skip_space
    
    done:
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
NewAtC
  • 55
  • 9
  • All whitespace or just ASCII 0x20 space? If the latter, `pcmpeqb xmm0, [rdi]` / with a vector constant / `pmovmskb` / `not` / `bsf` can find the first non-space in a vector of 16 bytes, and yeah you can do that in a loop. For a simple scalar version, you could write it in C or Rust or other "simple" language and look at compiler output. – Peter Cordes Nov 10 '21 at 16:08
  • 2
    The traditional x86 method would put the address of the string is `esi` and do something like `myloop: lodsb` / `cmp al, ' '` / `jne myloop`, although you'd probably want to check for end-of-string too. – Tim Roberts Nov 10 '21 at 19:24
  • @harold updated my question – NewAtC Nov 10 '21 at 19:28
  • You can use `rep scasb` to find not space char. – Igor Nov 10 '21 at 19:31
  • @Igor Where should I put it in the code? – NewAtC Nov 10 '21 at 19:40
  • Can somebody write code example? – NewAtC Nov 10 '21 at 20:35

2 Answers2

1

In this 16-bit code that fetches its string offset at buff+2, I believe it's a safe bet to consider this string to belong to the input gotten from executing the DOS.BufferedInput function 0Ah.
The code snippets below are based on this assumption. Next observations about the OP's code remain valid anyway.

  • The mov ah, [si] must be part of the loop. You need to verify different characters from the string, so loading following bytes is necessary.
  • Your code should exit the loop upon finding a non-space character. Currently you exit upon the first space.
  • The loop instruction requires setting up the CX register with the length of the string. You omitted that.
  mov  si, offset buff+2
  mov  cl, [si-1]
  mov  ch, 0
  jcxz done               ; String could start off empty
loop_skip_space:
  cmp  byte ptr [si], ' '
  jne  done
  inc  si                 ; Skip the current space
  loop loop_skip_space
done:

Here SI points at the first non-space character in the string with CX characters remaining. CX could be zero!


You can write better code if you stop using the loop instruction, because it's an instruction that is said to be slow. See Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?.

  1. Avoiding loop and no longer requiring the use of CX
  mov  si, offset buff+2
  mov  cl, [si-1]
  test cl, cl
  jz   done               ; String could start off empty
loop_skip_space:
  cmp  byte ptr [si], ' '
  jne  done
  inc  si                 ; Skip the current space
  dec  cl
  jnz  loop_skip_space
done:
  1. Avoiding loop and using the delimiter 13 (carriage return)
  mov  si, offset buff+1
loop_skip_space:
  inc  si
  cmp  byte ptr [si], ' '
  je   loop_skip_space
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
0

look at the example

    STRLEN    EQU  9
    STRING    DB   'Assembler'

              CLD                    ;clear direction flag
              MOV  AL,' '            ;symbol to find.
              MOV  ECX,STRLEN         ;length of string
              LEA  EDI,STRING         ;string pointer.
              REPE SCASB            ;search itself
              JNZ  K20               ;jump if not found
              DEC  EDI                ;
; EDI points to your first not space char
    K20:      RET
Igor
  • 1,589
  • 15
  • 15
  • 1
    The code for skipping the leading whitespace is wrong. You want to **repeat** the instruction **while** the character is **equal** to a space. Needs `REPE SCASB` – Sep Roland Nov 10 '21 at 23:55
  • For an all-spaces string, you need to use `JZ K20`. Only if a non-space was encountered, do you need to back up 1 character. – Sep Roland Nov 12 '21 at 23:10