使用 IRVINE32.inc 在 MASM 中检查回文
Palindrome Checking in MASM using IRVINE32.inc
我正在尝试检查字符串是否为回文。我正在尝试为此使用堆栈,即,将字符串压入堆栈并将其弹出到另一个字符串中,然后将它们进行比较。但是我的函数总是以 'Not a palindrome' 结束,即使它是
编辑:我将 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
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 “当我 assemble 时什么都不显示”。那是因为 Irvine32 只看到一个空字符串。以 0.
开头的字符串
并且检查回文将失败,因为这是两个字符串最后的样子(您比较的部分):
str1 65, 66, 66, 65
str2 0, 65, 66, 66
解决方案
将cmp BYTE PTR [esi], '$'
改为cmp byte ptr [esi], 0
删除 sub ecx, 1
将 mov str2[edi], '$'
更改为 mov str2[edi], 0
删除 sub ecx, 1
我正在尝试检查字符串是否为回文。我正在尝试为此使用堆栈,即,将字符串压入堆栈并将其弹出到另一个字符串中,然后将它们进行比较。但是我的函数总是以 'Not a palindrome' 结束,即使它是
编辑:我将 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
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 “当我 assemble 时什么都不显示”。那是因为 Irvine32 只看到一个空字符串。以 0.
开头的字符串并且检查回文将失败,因为这是两个字符串最后的样子(您比较的部分):
str1 65, 66, 66, 65
str2 0, 65, 66, 66
解决方案
将cmp BYTE PTR [esi], '$'
改为cmp byte ptr [esi], 0
删除 sub ecx, 1
将 mov str2[edi], '$'
更改为 mov str2[edi], 0
删除 sub ecx, 1