如何使用LC-3语言编写带三次错误锁定的用户名密码验证程序
LC-3用户名密码验证程序开发步骤
第一步:前置资源规划
- 首先在程序数据段预先定义所有固定内容:
- 正确的用户名、密码,用
.STRINGZ指令存储,自动带字符串终止符\0 - 各类提示文本:用户名输入提示、密码输入提示、校验错误提示、次数耗尽锁定提示、验证成功提示
- 预留输入缓冲区,用于存储用户输入的内容
- 预留1个内存单元作为错误次数计数器
- 正确的用户名、密码,用
- 提前确认用到的LC-3 TRAP指令:
PUTS(TRAP x21):输出字符串GETS(TRAP x22):读取用户输入的字符串到指定缓冲区HALT(TRAP x25):终止程序
第二步:用户名校验逻辑实现
- 初始化错误计数器为0
- 进入循环,最多执行3次:
- 打印用户名输入提示,读取用户输入到缓冲区
- 逐字符比较用户输入和预存的正确用户名:两个字符串同步遍历,只要出现字符不一致或者终止符出现时机不一致,就判定为不匹配
- 匹配成功:直接跳出循环,进入密码校验环节
- 匹配失败:错误计数器+1,打印错误提示,若计数器值等于3,直接打印锁定提示,调用HALT结束程序
第三步:密码校验逻辑实现
逻辑和用户名校验完全一致:
- 重置错误计数器为0
- 进入循环,最多执行3次:
- 打印密码输入提示,读取用户输入到缓冲区
- 逐字符比较用户输入和预存的正确密码
- 匹配成功:打印验证成功提示,正常结束程序
- 匹配失败:错误计数器+1,打印错误提示,若计数器值等于3,直接打印锁定提示,调用HALT结束程序
核心代码参考
.ORIG x3000 ; ========== 数据段定义 ========== RIGHT_USER .STRINGZ "admin" ; 预存正确用户名 RIGHT_PWD .STRINGZ "123456" ; 预存正确密码 PROMPT_U .STRINGZ "Enter username: " PROMPT_P .STRINGZ "Enter password: " ERR_U .STRINGZ "Username error, retry.\n" ERR_P .STRINGZ "Password error, retry.\n" LOCK .STRINGZ "Too many errors, program exit.\n" SUCCESS .STRINGZ "Auth success!\n" INPUT_BUF .BLKW #32 ; 输入缓冲区,最大32字符 ERR_CNT .FILL #0 ; 错误计数器 ; ========== 用户名校验 ========== USER_CHECK AND R0, R0, #0 ST R0, ERR_CNT ; 错误计数清零 USER_LOOP LD R0, PROMPT_U PUTS ; 输出用户名提示 LD R0, INPUT_BUF GETS ; 读取用户输入 ; 字符串比较逻辑 LEA R1, RIGHT_USER LD R2, INPUT_BUF CMP_U_LOOP LDR R3, R1, #0 LDR R4, R2, #0 BRZ CMP_U_END ; 正确用户名遍历结束 NOT R3, R3 ADD R3, R3, #1 ADD R3, R3, R4 BRNP CMP_U_FAIL ; 字符不匹配 ADD R1, R1, #1 ADD R2, R2, #1 BR CMP_U_LOOP CMP_U_END LDR R4, R2, #0 BRZ CMP_U_SUCCESS ; 用户输入也到结尾,匹配成功 CMP_U_FAIL LD R0, ERR_U PUTS LD R0, ERR_CNT ADD R0, R0, #1 ST R0, ERR_CNT ADD R0, R0, #-3 BRZ EXIT_LOCK ; 错误3次,锁定退出 BR USER_LOOP CMP_U_SUCCESS ; ========== 密码校验和用户名逻辑一致,此处省略重复实现 ========== EXIT_LOCK LD R0, LOCK PUTS HALT EXIT_SUCCESS LD R0, SUCCESS PUTS HALT .END
调试注意点
- 字符串比较时注意必须同时遍历到两个字符串的终止符
\0才判定为匹配,避免短输入前缀匹配绕过校验的问题 - 输入缓冲区的大小要大于你预设的用户名、密码最大长度,避免内存溢出
- 可以先用LC-3模拟器单步执行验证3次错误退出、正确输入跳转、密码校验等分支逻辑
内容的提问来源于stack exchange,提问作者Alex Park
相关产品推荐
相关产品推荐

