【问题标题】:How to remove characters counting from the end of a string?如何删除从字符串末尾计数的字符?
【发布时间】:2016-05-05 13:06:24
【问题描述】:

我必须从字符串末尾删除一定数量的字符(比如说 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

【问题讨论】:

  • 你不需要填零,你只需要一个。对于编译时常量字符串,您可以只使用LENGTHOF,因为您不需要任何搜索。另请注意,'0'0 的 ascii 代码,它不是 0 而是 48,所以这不是您想要的。
  • 您对这个问题的三次尝试中至少有一次没有结束。 :)
  • 我的荣幸。这似乎更接近地反映了“如何提出问题”wiki 所说的内容。

标签: assembly x86 masm masm32 irvine32


【解决方案1】:

错误是你没有用任何值重置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

请注意,在第一个 “将 W 之后的所有字符存储为 0” 是不正确的。您必须在 SUB EDI, 3 之后执行 ADD ECX, 3 才能做到这一点。

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

【讨论】:

  • 第二部分用 mov edi 替换 mov al, 0, 0 仍然打印出整个字符串。
  • @JoeDoe 注意它是MOV [EDI], 0,而不是MOV EDI, 0。实际上也应该有数据大小。所以MOV BYTE PTR [EDI], 0 所以它将零存储到EDI 指向的内存中,而不是EDI
  • 现在可以使用了。谢谢。也感谢您在回答中的解释。
猜你喜欢
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-07
  • 1970-01-01
相关资源
最近更新 更多