使用 IRVINE32.inc 在 MASM 中检查回文

Posted

技术标签:

【中文标题】使用 IRVINE32.inc 在 MASM 中检查回文【英文标题】:Palindrome Checking in MASM using IRVINE32.inc 【发布时间】:2021-11-27 12:59:41 【问题描述】:

我正在尝试检查一个字符串是否为回文。我正在尝试为此使用堆栈,即,将字符串推入堆栈并将其弹出另一个字符串,然后将它们两者进行比较。但我的函数最终总是说“不是回文”,即使它是。

编辑:我将 str1 作为用户的输入。

str1 BYTE 30 DUP('$')

下面是我写的函数

checkPalindrome PROC
    pop address


    mov esi , offset str1
    mov ecx, lengthof str1

    ;push till last index of str1
    L1:
        cmp BYTE PTR [esi], '$'
        je exitLoop
        push [esi]
        inc esi
    loop L1
    exitLoop:

    mov edi, 0
    sub ecx, 30
    neg ecx

    mov lengthStr, ecx
    sub ecx, 1

    L2:
        pop eax
        mov str2[edi], al
        inc edi
    loop L2

    mov str2[edi], '$'
    
   ;this displays nothing when i assemble
    mov edx, offset str2
    call writeString


    mov esi, offset str1
    mov edi, offset str2

    mov ecx, lengthStr
    sub ecx, 1
    L0:
        mov eax, [esi]
        mov ebx, [edi]
        cmp al, bl
        jne notPalind

        inc esi
        inc edi
    loop L0



    isPalind:
    mov edx, offset isPalindrome
    call writeString
    jmp quit

    notPalind:

    mov edx, offset notPalindrome
    call writeString

    quit:
    push address
    ret
checkPalindrome ENDP

【问题讨论】:

你试过单步调试吗?对于初学者,请尝试一个非常小的示例,例如空字符串或只是“a”,然后是“aa”或“ab”。 根据您输入字符串的方式,最后可能有一个零终止符。该代码似乎可以工作,即使它过于复杂。 【参考方案1】:

Irvine32 不使用以 $ 结尾的字符串。那是 DOS 的东西!

鉴于您的全部定义str1 BYTE 30 DUP('$'),并采取例如。 “ABBA”的输入,缓冲区看起来像:

65, 66, 66, 65, 0, 36, 36, 36, 36, 36, ...

您的第一个循环将在找到“$”字符后退出之前将 5 个项目推入堆栈。

00000041
00000042
00000042
00000041
00000000  <-- ESP
sub ecx, 30
neg ecx
mov lengthStr, ecx
sub ecx, 1

上面的计算将设置lengthStr=5,您发现它已经比实际输入多 1,因此您减去 1。尽管如此,这并没有帮助,因为堆栈仍然包含 5 个项目,而第一个退出的项目将是那个终止的零,后来搞砸了回文的比较。 这是 str2 在 $- 终止后的样子:

0, 65, 66, 66, 34

你写了关于 str2 “这在我组装时什么都不显示”。那是因为 Irvine32 只看到一个空字符串。以 0 开头的字符串。

并且检查回文将失败,因为这就是两个字符串最终的样子(您比较的部分):

str1   65, 66, 66, 65
str2    0, 65, 66, 66

解决方案

cmp BYTE PTR [esi], '$' 更改为cmp byte ptr [esi], 0 删除sub ecx, 1mov str2[edi], '$' 更改为mov str2[edi], 0 删除sub ecx, 1

【讨论】:

以上是关于使用 IRVINE32.inc 在 MASM 中检查回文的主要内容,如果未能解决你的问题,请参考以下文章

如何将Assembly(irvine masm)中的字符串初始化回null?

组装(masm)数组操作

在 Assembly x86 MASM 中连接字符串和数组的大小

如何使用 DWORD PTR(汇编语言)打印负整数

MASM x86 如何打印多行字符串变量?

ReadConsoleInputA 引发访问冲突