64位Intel架构NASM汇编如何实现用户输入上下界校验纠错
x86-64汇编输入范围校验实现方案
现有代码核心问题
当前预留的_checkVal逻辑存在两个基础错误,无法直接实现校验需求:
_getVal调用read系统调用读到value缓冲区的是用户输入的ASCII编码字符串,例如输入12实际存储的是字节0x31、0x32、0x0A(换行符),直接用mov eax, value加载的是ASCII字节值,不是可用于数值比较的整数。- 没有设计非法输入的提示、重入读取的循环逻辑,输入错误时无法回到输入流程。
第一步:补充.data段所需定义
放开之前注释的边界值,新增非法输入提示字符串即可:
section .data text1 db "Enter shift value: " text2 db "Enter original message: " text3 db "Current message: " text4 db "Encryption: " invalidMsg db "Invalid input! Please enter a number between 0 and 25: " invalidLen equ $ - invalidMsg ; 自动计算提示字符串长度 lowBound dword 0 upBound dword 25
第二步:替换原有_checkVal实现
完整的校验逻辑包含ASCII字符串转整数、输入合法性判断、非法输入重输三个模块,直接替换现有空的_checkVal函数即可:
_checkVal: xor rax, rax ; rax存储转换后的整数值,初始清零 xor rcx, rcx ; rcx作为输入缓冲区的遍历索引,初始清零 mov rbx, value ; rbx指向value输入缓冲区首地址 convert_loop: movzx rdx, byte [rbx + rcx] ; 读取当前索引位置的1个字符,零扩展到rdx cmp rdx, 0x0A ; 匹配到换行符说明输入字符串读取结束 je convert_finish ; 校验当前字符是否为数字 cmp rdx, '0' jb input_error cmp rdx, '9' ja input_error ; 合法数字字符转整数值:累计值 = 累计值 *10 + (当前字符ASCII - '0') sub rdx, '0' imul rax, 10 add rax, rdx ; 提前溢出判断:转换中数值已经超过25直接判定非法,避免无效计算 cmp rax, 25 ja input_error inc rcx ; 索引自增,处理下一个字符 jmp convert_loop convert_finish: cmp rcx, 0 ; 索引为0说明用户直接敲回车,是空输入 je input_error ; 最终范围校验 cmp rax, [lowBound] jb input_error cmp rax, [upBound] ja input_error ; 所有校验通过,把转换好的整数存回value位置,返回主流程 mov [value], rax ret input_error: ; 打印非法输入提示 mov rax, 1 mov rdi, 1 mov rsi, invalidMsg mov rdx, invalidLen syscall ; 重新读取用户输入 call _getVal ; 跳转回校验逻辑,直到输入合法才会返回 jmp _checkVal
关键说明
- 校验通过后,
value标签指向的内存存储的是已经转换完成的0-25区间整数,后续凯撒加密的位移逻辑可以直接读取该值使用,不需要再做字符串转整数处理。 - 逻辑覆盖所有非法场景:非数字输入、空输入、小于0/大于25的数字输入,所有非法场景都会触发提示并要求重新输入。
- 适配64位Intel架构Linux系统调用约定,不需要额外修改主函数流程,原有main中的调用逻辑可以正常运行。
内容的提问来源于stack exchange,提问作者Damnable Blue
相关产品推荐
相关产品推荐

