16位汇编字符串比较功能失效,疑似存在Bug?
问题分析与修复
你的代码存在两个关键问题,导致输入cupcake后无法正确触发correct逻辑并显示成功信息:
1. correct标签后的执行流程错误
在correct分支中,你设置了si指向correctkey但没有调用printText函数,而是直接进入了printText的函数体代码。这会导致:
- 执行完
printText的ret指令时,栈顶的返回地址是之前调用printText(打印correctnewline)时压入的地址,会跳回mov si, correctkey这一行,形成死循环。 - 最终程序可能崩溃,无法正常显示成功提示。
修复方法:在mov si, correctkey后添加call printText,并在最后加入无限循环防止执行后续数据区代码:
correct: mov si, correctnewline call printText mov si, correctkey call printText jmp $ ; 无限循环,避免执行后续数据
2. inputString缓冲区定义错误
你的inputString times 8 db " ", 0写法会重复8次db " ", 0,生成16字节的缓冲区(8个空格+8个null),这不符合输入存储的预期(我们只需要8字节存储7个字符+1个终止符)。正确的定义应该是:
inputString times 8 db ' '
修复后的完整代码
ORG 0x7C00 BITS 16 jmp getUserInput ; Call function 'getUserInput' incorrect: mov si, invalidKey ; Set text to SI register call printText ; Call print text function getUserInput: mov si, msg ; Set greeting text to SI register call printText ; Call print text function mov di, inputString ; set up the string to be read in into di getKeyLoop: mov ah, 0x00 ; Set function 'Reading' for interrupt 16h int 0x16 ; Use 16h interrupt to read next char from keyboard mov ah, 0x0e ; Set char types and colors cmp al, 0xD ; when enter button is pressed... je getCheckKey ; compare the string entered int 0x10 ; otherwise use 10h interrupt to display character mov [di], al ; Move AL to memory of DI address inc di ; DI += 1; increments the address of DI to store the next character jmp getKeyLoop ; Loop | jump to function 'getKeyLoop' getCheckKey: mov byte [di], 0 ; add null terminator to the end of inputString mov di, inputString ; move input string into di mov si, password ; copy password to si for comparison CheckKeyLoop: mov al, [di] ; move 1st character or inputString into al mov cl, [si] ; move 1st character of key into cl cmp cl, al ; compare 1st character of both strings jne incorrect ; if they don't match, jump back to getUserInput but print incorrect message first cmp al, 0 ; otherwise compare to null terminator je correct ; password match inc di ; otherwise check next char inc si ; check next char jmp CheckKeyLoop ; resume the loop correct: mov si, correctnewline call printText mov si, correctkey call printText jmp $ ; 无限循环,防止执行后续数据 printText: ; Function 'printText' mov ah, 0x0e ; Set the text print mode mov bh, 0x00 ; Set screen and text parameters mov bl, 0x07 ; Set screen and text parameters printChar: mov al, [si] ; Move character from si (dereferenced) to al cmp al, 0 ; If AL = 0... je endPrinting ; Call function 'endPrinting' ; Else... int 0x10 ; Use 10h interrupt add si, 1 ; Move +1 to SI register (inc si) jmp printChar ; Loop back up to 'printChar' function. endPrinting: ; Function 'endPrinting' ret ; Return password db "cupcake", 0 msg db " Enter the password: ", 0 invalidKey db " <= Incorrect. Try again..", 13, 10, 0 inputString times 8 db ' ' correctnewline db " ", 13, 10, 0 correctkey db " Congratulations!", 13, 10, 0 times 510 - ($-$$) db 0 dw 0xAA55
验证修复
重新编译运行:
nasm -f bin -o cmp-input.bin cmp-input.asm qemu-system-x86_64 cmp-input.bin
输入cupcake并回车,就能看到成功提示了。
内容的提问来源于stack exchange,提问作者unixpipe
相关产品推荐
相关产品推荐

