我对汇编非常陌生,目前正在尝试编写一个程序,该程序使用用户指定的密钥和用户指定的内容执行凯撒加密。密钥和内容必须是 a-z 或 A-Z,为了验证这一点,我构建了一个简单的算法来检查 ASCII 值是否在相应的范围内。问题是,即使给定普通字符 a-z 或 A-Z,它仍然返回 false。
这是我的算法的最小可重现示例。即使给算法提供了“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
目前,这是我看到问题的地方,但我会继续寻找:
_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 ; of-by-one error -> should be `je`
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] -> not needed
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
_pti_loop: cmp rbx, [len_text_input] jg _pti_end
在此循环开始时,RBX 仍为零,并且假设 len_text_input 是非负数,则 RBX 不可能大于 [0,maxint] 范围内的数字。因此,您的代码将无法捕获空字符串,并且通常它会处理过多的一个字符!如果您使用
jge
甚至 je
那就没问题了。
add al, [key] cmp al, 122 jg _fix_overhang
对于此凯撒加密,key 在 [0,25] 范围内。一旦确定要处理的是 [97,122] 范围内的 ASCII 小字符 a-z,就可以添加键。此加法的结果可高达 147。因为您使用的是有符号条件指令
jg
,其中 [128,255] 范围内的所有数字都被视为负数,所以更大的条件可能不适用,因此“悬垂”可能无法修复。
下一个改进的解决方案还删除了一些冗余,例如多次从
[text_input + rbx]
重新加载。
_process_text_input:
cmp byte [text_input], 10
je _no_text_error
xor rbx, rbx
cmp [len_text_input], rbx
je _pti_end
_pti_loop:
movzx eax, byte [text_input + rbx]
mov edx, 'Z'
cmp al, 'A'
jb _bad_text_error
cmp al, 'Z'
jbe _add_key
cmp al, 'a'
jb _bad_text_error
cmp al, 'z'
ja _bad_text_error
or edx, 32 ; -> EDX = 'z'
_add_key:
add al, [key] ; key = [0,25]
cmp al, dl ; DL = {'Z','z'}
jbe _store
sub al, 26 ; fix overhang
_store:
mov [output + rbx], al
inc rbx
cmp rbx, [len_text_input]
jb _pti_loop
_pti_end:
ret