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

汇编实现凯撒加密时ASCII字符校验异常求助

凯撒加密程序的字符校验故障排查与修复

我刚接触汇编语言,正在编写一款支持用户指定密钥与内容的凯撒加密程序。要求密钥和内容必须为a-z或A-Z字符,为此编写了简单算法校验其ASCII值是否在对应范围内,但即便输入正常的a-z/A-Z字符,校验仍返回错误。

以下是算法的最小可复现示例,输入字符'a'却仍返回错误,查阅ASCII表后仍无法定位问题:

section .text
  global _start

_start:
cmp byte [char], 122
jg _error
cmp byte [char], 96
jg _success
cmp byte [char], 90
jg _error
cmp byte [char], 64
jg _success
jmp _error

_success:
  mov rax, 1
  mov rdi, 1
  mov rsi, success
  mov rdx, len_success
  syscall
  xor rbx, rbx
  jmp _exit

_error:
  mov rax, 1
  mov rdi, 2
  mov rsi, error
  mov rdx, len_error
  syscall
  mov rbx, 1
  jmp _exit

_exit:
  mov rax, 60
  mov rdi, rbx
  syscall

section _data
  char db 'a'
  error db "Error"
  len_error equ $ - error
  success db "Success"
  len_success equ $ - success

实际处理文本的算法如下:

_process_text_input:
  cmp byte [text_input], 10
  je _no_text_error
  xor rbx, rbx
  jmp _pti_loop
_pti_loop:
  cmp rbx, [len_text_input]
  jg _pti_end
  mov al, [text_input+rbx]
  cmp al, 97
  jl _process_capital_char
  cmp al, 122
  jg _bad_text_error
  add al, [key]
  cmp al, 122
  jg _fix_overhang
  mov byte [output+rbx], al
  inc rbx
  jmp _pti_loop
_process_capital_char:
  cmp byte [text_input+rbx], 90
  jg _bad_text_error
  cmp byte [text_input+rbx], 65
  jl _bad_text_error
  mov al, [text_input+rbx]
  add al, [key]
  cmp al, 90
  jg _fix_overhang
  mov byte [output+rbx], al
  inc rbx
  jmp _pti_loop
_fix_overhang:
  sub al, 26
  mov byte [output+rbx], al
  inc rbx
  jmp _pti_loop
_pti_end:
  ret

问题根源与修复方案

最小复现示例的核心问题

  1. 段名语法错误:NASM中数据段的正确声明是section .data或.data,你写的section _data是无效段名,导致char变量未被正确加载到数据段,程序读取的是随机垃圾值,自然触发错误。把section _data改成section .data即可解决基础问题。
  2. 校验逻辑顺序冗余:现有校验逻辑虽然能工作,但顺序混乱易出错。优化后的清晰校验逻辑如下:
_start:
cmp byte [char], 65
jl _error          ; 小于'A',错误
cmp byte [char], 90
jle _success       ; 在'A'-'Z'之间,成功
cmp byte [char], 97
jl _error          ; 在'Z'-'a'之间,非字母,错误
cmp byte [char], 122
jle _success       ; 在'a'-'z'之间,成功
jmp _error

实际算法的问题与修复

  1. 重复内存访问:_process_capital_char中重复读取[text_input+rbx],可以直接复用_pti_loop中已加载到al的字符值,减少不必要的内存操作。
  2. 密钥处理错误:直接add al, [key]会使用密钥字符的ASCII值作为偏移量(比如输入密钥'3'会加51),这完全不符合凯撒加密的偏移逻辑。需要先将密钥字符转换为0-25的数值:
    ; 假设密钥是小写字符,转换为偏移量
    mov bl, [key]
    sub bl, 97
    mov [key_num], bl
    
  3. 循环边界判断错误:cmp rbx, [len_text_input]后用jg会漏掉rbx等于长度的情况,应该改用jge,此时所有字符已处理完毕,需退出循环。
  4. 代码冗余优化:合并重复的存储与跳转逻辑,让代码更简洁易维护。

修复后的实际算法示例:

_process_text_input:
  cmp byte [text_input], 10
  je _no_text_error
  xor rbx, rbx
_pti_loop:
  cmp rbx, [len_text_input]
  jge _pti_end  ; 长度相等时退出循环
  mov al, [text_input+rbx]
  
  ; 检查小写字母范围
  cmp al, 97
  jge .check_lower_bound
  ; 检查大写字母范围
  cmp al, 65
  jl _bad_text_error
  cmp al, 90
  jg _bad_text_error
  
  ; 处理大写字母偏移
  add al, [key_num]
  cmp al, 90
  jle .store_result
  sub al, 26
  jmp .store_result
  
.check_lower_bound:
  cmp al, 122
  jg _bad_text_error
  ; 处理小写字母偏移
  add al, [key_num]
  cmp al, 122
  jle .store_result
  sub al, 26
  
.store_result:
  mov byte [output+rbx], al
  inc rbx
  jmp _pti_loop
_pti_end:
  ret

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 10:03:11