如何在汇编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:

在这个在buff+2处获取字符串偏移量的16位代码中,我相信可以安全地将此字符串视为执行DOS.BufferdInput函数0Ah所获得的输入
下面的代码片段基于这一假设。接下来对OP代码的观察仍然有效。

  • mov ah, [si]必须是循环的一部分。您需要验证字符串中的不同字符,因此需要加载以下字节
  • 您的代码应该在找到非空格字符后退出循环。当前您在第一个空间退出
  • 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指向字符串中剩余CX个字符的第一个非空格字符。CX可能为零!


如果停止使用loop指令,您可以编写更好的代码,因为据说这是一条速度较慢的指令。请参阅为什么循环指令慢?无法';英特尔没有有效地实现它吗?。

  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(回车(
mov  si, offset buff+1
loop_skip_space:
inc  si
cmp  byte ptr [si], ' '
je   loop_skip_space

查看示例

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

最新更新