用于DOS的x86程序集中的回文检查代码中的错误

时间:2013-03-26 08:19:08

标签: assembly x86 dos

此代码应检查字符串是否为palindome。

但它总是为任何字符串打印“是”。我该如何解决这个问题?

我认为错误出现在一些跳转指令中。

错误是什么?

include inout.asm
.model small,c
.stack 200h
.data
    pal       db "rear"
    ;pal      db 200 dup("mohammad")
    pal_len   equ $ - pal  - 1
    szYes     db "yes$"
    szNo      db "no$"
.code
.startup

;call gets,offset pal
call puts,offset pal

    lea     si, pal
    lea     di, pal
    add     di, pal_len
    mov     cx, 0
CheckIt:
    mov     al, byte ptr [si]
    mov     dl, byte ptr [di]
    cmp     al, dl
    jne     No
    inc     si
    dec     di
    inc     cx
    cmp     cx, pal_len
    JNE     CheckIt
    lea     dx,szYes

    jmp done

No:
    lea     dx,szNo
done:   
    .exit
end

1 个答案:

答案 0 :(得分:0)

我在你的问题中看不到打印代码。所以我添加了自己的:

No:
    lea dx,szNo
done:
    mov ah,9
    int 21h
    .exit
end

并将其与MASM 6.11组装在一起,并为“后方”打印“否”,应该如此,并且我也尝试过其他字符串。我不知道您使用的打印代码。

但是,您的代码中还有其他错误:它不能正确处理长度为1的字符串,但会在pal之后继续比较内存中的任何字节。这是因为您将pal_len存储在最后一个字符的相对偏移量中,而不是字符串长度,并使用{{cx增加inc cx 1}}在检查cx是否已经等于pal_len之前。

所以这里:

pal_len equ $ - pal  - 1

pal_len定义为"rear"的值为3,而不是4,因为你减去1.这里除了1以外的字符串长度没有问题(最后一个字符已经比较了第一个字符),但是字符串长度为1则失败。用长度中的“len”命名变量或宏,并使用它来表示偏移是不是一个好主意,因为它会造成混乱。

所以,这是整个固定代码:

.model small,c
.stack 200h
.data
    pal db "a"
    pal_len equ $ - pal
    szYes     db "yes$"
    szNo      db "no$"
.code
.startup

    lea     si, pal
    lea     di, pal
    add     di, (pal_len-1)
    mov     cx, 0
CheckIt:
    mov     al, byte ptr [si]
    mov     dl, byte ptr [di]
    cmp     al, dl
    jne     No
    inc     si
    dec     di
    inc     cx
    cmp     cx, pal_len
    JNE     CheckIt
    lea     dx,szYes

    jmp     done

No:
    lea     dx,szNo
done:
    mov     ah,9
    int     21h
    .exit
end