You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改8086汇编代码实现密码输入不回显?

8086汇编实现无回显密码输入与验证

问题描述

现有一段8086汇编代码用于密码验证,原代码使用int 21h ah=0AH读取用户输入,希望修改为输入密码时不回显字符。尝试过int 21h ah=08h、循环调用int 16h ah=00h或int 21h ah=08h,虽能实现无回显,但无法将输入存入声明的缓冲区用于后续比对,求解决方法。

原代码:

.MODEL SMALL
.STACK 100H
.DATA
    MSG DB 'Enter password: $'
    DISPLAY_MSG DB 0dh, 0ah, 'NAME: display name', 0dh, 0ah, 'ID NUMBER: display number', '$'
    ERROR_MSG DB 'Password does not match.!$'
    PASSWORD DB '123'
    BUFFER DB 4
.CODE
    MAIN PROC
        MOV AX, @DATA
        MOV DS, AX
        LEA DX, MSG
        MOV AH, 9
        INT 21H ; print prompt message
        
        MOV AH, 0AH
        LEA DX, BUFFER
        INT 21H ; read input from user

        
        MOV SI, OFFSET BUFFER+2 ; skip first byte (input length)
        MOV DI, OFFSET PASSWORD
        MOV CX, 3 ; compare up to 6 characters
    CMP_LOOP:
        LODSB ; load byte from SI into AL, increment SI
        CMP AL, [DI] ; compare with password character
        JNE CMP_FAIL ; jump to failure if not equal
        INC DI ; move to next password character
        LOOP CMP_LOOP ; repeat until CX is zero
        JMP SUCCESS
    CMP_FAIL:
        ; passwords don't match, print error message
        LEA DX, ERROR_MSG
        MOV AH, 9
        INT 21H
    SUCCESS:
        ; passwords match, print success message
        LEA DX, DISPLAY_MSG
        MOV AH, 9
        INT 21H
        
        MOV AH, 4CH
        INT 21H ; return to DOS
    MAIN ENDP
    END MAIN

解决方案

核心思路是通过循环调用int 21h ah=08h逐个读取字符(无回显),并将读取到的字符手动存入缓冲区,同时可选择输出*反馈用户输入,最后沿用原有的密码比对逻辑。

修改后的完整代码:

.MODEL SMALL
.STACK 100H
.DATA
    MSG DB 'Enter password: $'
    DISPLAY_MSG DB 0dh, 0ah, 'NAME: display name', 0dh, 0ah, 'ID NUMBER: display number', '$'
    ERROR_MSG DB 'Password does not match.!$'
    PASSWORD DB '123'
    ; 调整缓冲区结构:最大长度、实际长度、存储区(预留4字节,含结束符)
    BUFFER DB 4, ?, 4 DUP(?)
.CODE
    MAIN PROC
        MOV AX, @DATA
        MOV DS, AX
        LEA DX, MSG
        MOV AH, 9
        INT 21H ; 打印提示信息
        
        ; 无回显读取密码,存入BUFFER
        MOV CX, 3 ; 密码长度为3
        MOV DI, OFFSET BUFFER+2 ; 指向存储区起始位置
    READ_LOOP:
        MOV AH, 08H
        INT 21H ; 无回显读取字符到AL
        
        CMP AL, 0DH ; 判断是否按下回车
        JE END_READ ; 提前回车则结束读取
        
        MOV [DI], AL ; 将字符存入缓冲区
        INC DI
        
        ; 可选:输出*反馈输入
        MOV AH, 02H
        MOV DL, '*'
        INT 21H
        
        LOOP READ_LOOP
    END_READ:
        ; 确保缓冲区输入长度字段正确(可选,用于后续判断输入长度)
        MOV BL, OFFSET BUFFER+2
        SUB DI, BL
        MOV BUFFER+1, BL
        
        ; 密码比对逻辑(沿用原逻辑)
        MOV SI, OFFSET BUFFER+2
        MOV DI, OFFSET PASSWORD
        MOV CX, 3 ; 比对3个字符
    CMP_LOOP:
        LODSB
        CMP AL, [DI]
        JNE CMP_FAIL
        INC DI
        LOOP CMP_LOOP
        JMP SUCCESS
    CMP_FAIL:
        LEA DX, ERROR_MSG
        MOV AH, 9
        INT 21H
        JMP EXIT ; 失败后直接退出,避免执行SUCCESS逻辑
    SUCCESS:
        LEA DX, DISPLAY_MSG
        MOV AH, 9
        INT 21H
    EXIT:
        MOV AH, 4CH
        INT 21H ; 返回DOS
    MAIN ENDP
    END MAIN

关键修改说明

  • 缓冲区结构调整:将原BUFFER DB 4改为BUFFER DB 4, ?, 4 DUP(?),符合DOS输入缓冲区的标准结构(最大长度、实际输入长度、输入内容存储区),方便后续管理输入内容。
  • 无回显读取循环:用CX控制读取次数(对应密码长度3),每次调用int 21h ah=08h读取字符,不回显到屏幕;若用户提前按回车,直接跳出循环。
  • 手动存入缓冲区:将读取到的字符(AL寄存器)存入BUFFER+2起始的存储区,同时维护缓冲区的实际长度字段(BUFFER+1)。
  • 输入反馈优化:可选输出*字符,让用户感知输入操作,提升交互体验。
  • 逻辑修正:在密码比对失败后添加JMP EXIT,避免执行后续成功提示的代码。

内容的提问来源于stack exchange,提问作者Zatania

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 09:35:28