如何删除从字符串末尾开始计数的字符?

How to remove characters counting from the end of a string?

我必须从字符串末尾删除一定数量的字符(比如说 3 个)。对于这个特定的字符串,它在我找到 'Z' 时起作用,然后通过 sub edi 3 使其指向 W,然后将字符串的其余部分存储为 0。

INCLUDE Irvine32.inc

.data
source BYTE "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0

.code
main PROC

mov edi, OFFSET source
mov al, 'Z'                  ; search for Z
mov ecx, LENGTHOF source
cld
repne scasb       ; repeat while not equal
sub edi, 3         ; now points to W

mov al, 0         
rep stosb        ; stores all characters after W with 0.

mov edx, OFFSET source
call WriteString
call CrlF

exit
main ENDP
end main

但是,我想让这段代码适用于不同的空终止字符串。为此,我尝试查找 0(字符串的末尾),如下面的代码所示。但它不起作用,它只是输出整个字符串。

我应该怎么做才能确保即使字符串被更改代码仍然有效而不必每次都更改对字符串结尾的搜索?

INCLUDE Irvine32.inc

.data
source BYTE "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0

.code
main PROC

mov edi, OFFSET source
mov al, '0'                  ; search for end of string
mov ecx, LENGTHOF source
cld
repne scasb       ; repeat while not equal
sub edi, 3         ; now points to W ??

mov al, 0         
rep stosb        ; stores all characters after W with 0.

mov edx, OFFSET source
call WriteString
call CrlF

exit
main ENDP
end main

错误是您没有用任何值重置 ECX

你设置ECX为数据的长度,在本例中为27。然后你找到Z,这是第26个值,所以最后ECX的值为1 并且您的 rep stosb 将在字符串中写入一个 0 。然后你打印它,第一个 nul 将停止打印。

在第二个中,您正在寻找 0,这是最后一个字节。退出 repne scasb ECX 是零,所以 rep stosb 不写任何东西。

要解决此问题,您可以使用

mov edi, OFFSET source
mov al, 0                  ; search for end of string
mov ecx, LENGTHOF source
cld
repne scasb       ; repeat while not equal
sub edi, 3         ; now points to W ??

mov byte ptr [edi], 0     ; store a single nul since that's enough

请注意第一个 "stores all characters after W with 0" 是不正确的。您必须在 SUB EDI, 3 之后执行 ADD ECX, 3 才能做到这一点。

还要注意 '0' 是字符 0,而不是值 0。