首先,将此视为从一个地方复制到同一个地方;其中不复制需要忽略的字节。为此,您需要 2 个寄存器 - 一个用于跟踪从哪里获取下一个字节(例如,也许esi
),以及一个用于跟踪存储下一个字节/字母的位置(例如,也许edi
).
其次,您的“is it a letter”分支不正确(例如,字母“A”或值 0x41 将小于字母“a”或值 0x61)。它需要更像:
cmp al,'A' ;Is the value too low to be any letter?
jb .notLetter ; yes
cmp al,'z' ;Is the value too high to be any letter?
ja .notLetter ; yes
cmp al,'Z' ;Is the value low enough to be a capital letter?
jbe .isLetter ; yes
cmp al,'a' ;Is the value high enough to be a lower case letter?
jae .isLetter ; yes
; no, not a letter
.notLetter:
例如(NASM):
;Inputs:
; ecx Length of original string
; esi Address of original string
;
;Outputs
; edi Length of new string
; ebx Address of new string
filterString:
mov edi,esi ;edi = address to store string (same address as original string)
mov ebx,esi ;ebx = address of both strings (used later)
jecxz .done ;Do nothing if the original string has zero length
cld
.nextByte:
lodsb ;AL = next byte, ESI incremented
cmp al,'A' ;Is the value too low to be any letter?
jb .doneByte ; yes, not a letter
cmp al,'z' ;Is the value too high to be any letter?
ja .doneByte ; yes, not a letter
cmp al,'Z' ;Is the value low enough to be a capital letter?
jbe .isLetter ; yes, it's a capital letter
cmp al,'a' ;Is the value high enough to be a lower case letter?
jb .doneByte ; no, not a letter
; yes, it's a lower case letter
.isLetter:
stosb ;Store AL at EDI, and increment EDI
.doneByte:
loop .nextByte
.done:
sub edi,ebx ;edi = length of new string
ret