如何在程序集 x86 中跳过字符串开头的空格

How to skip spaces at the beginning of the string in assembly x86

我应该写什么循环如果我想跳过字符串开头的所有空格并在我的代码到达字符串的第一个符号时开始对字符串做一些事情。如果我有一个像

这样的字符串
a='        s o m e word'

代码应在达到 's' 时开始。这应该是某种循环,但我仍然不知道如何正确编写它。

我的尝试:

    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:

看例子

    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

在这个 16 位代码中,它在 buff+2 处获取其字符串偏移量,我相信可以安全地认为这个字符串属于从执行 .[= 获得的输入。 33=] 下面的代码片段基于此假设。无论如何,接下来对 OP 代码的观察仍然有效。

  • mov ah, [si] 必须是循环的一部分。您需要验证字符串中的不同字符,因此需要加载以下字节。
  • 您的代码应在找到 非space 字符后退出循环。当前您在第一个 space.
  • 退出
  • loop 指令需要用字符串的长度设置 CX 寄存器。你忽略了那个。
  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:

此处 SI 指向字符串中的第一个非 space 字符,剩余 CX 个字符。 CX 可以为零!


如果您停止使用 loop 指令,您可以编写更好的代码,因为据说该指令很慢。参见 Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?

  1. 避免 loop 并且不再需要使用 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. 避免loop并使用定界符13(回车return)
  mov  si, offset buff+1
loop_skip_space:
  inc  si
  cmp  byte ptr [si], ' '
  je   loop_skip_space