我的代码有关于Caesar密码的问题。我不打算将我的评论改为英语,但反正他们并不多。该计划由两个计划组成。一个是编码Caesar密码,第二个是解码Caesar密码。我这样做的时候按0,它应该运行编码部分,当我按1时它应该运行解码部分。
编码程序应该像"0" -> "abc" -> "A" -> "bcd"
一样工作,并且解码会生成“zab”。
非常好,无论何时按0或1,它都会进行编码或解码。例如,如果有:
cmp $'0' , %bl
je LOOP1
cmp $'1' , %bl
je LOOP2
程序将在0之后运行,并在1次编码之后运行。如果我改变它看起来像它看起来完整的代码,它将运行解码即使我按0(与1相同)。所以可能比较错误..
完整代码:
SYSCALL = 0X80
STDIN = 0
STDOUT = 1
SYSREAD = 3
SYSWRITE = 4
SYSEXIT = 1
EXIT_SUCCESS = 0
.data
msg_hello: .ascii "0-kodowanie 1-dekodowanie"
msg_hello_len = . - msg_hello
WYBOR_MAXLEN = 1
WYBOR: .space WYBOR_MAXLEN
WYBOR_LEN: .long 0
TEXT_MAXLEN = 64
TEXT: .space TEXT_MAXLEN
TEXT_LEN: .long 0
KEY_MAXLEN = 2
KEY: .space KEY_MAXLEN
KEY_LEN: .byte
.text
.global _start
_start:
#wczytanie powitania
mov $SYSWRITE, %eax
mov $STDOUT, %ebx
mov $msg_hello, %ecx
mov $msg_hello_len, %edx
int $SYSCALL
# wczytanie 01
mov $TEXT_MAXLEN, %edx
mov $TEXT, %ecx
mov $STDIN, %ebx
mov $SYSREAD, %eax
int $SYSCALL
mov %ebx, WYBOR_LEN # wybor
# wczytanie tekstu
mov $TEXT_MAXLEN, %edx
mov $TEXT, %ecx
mov $STDIN, %ebx
mov $SYSREAD, %eax
int $SYSCALL
mov %eax, TEXT_LEN # rzeczywista dlugosc wczytanego tekstu
#wczytywanie klucza
mov $KEY_MAXLEN, %edx
mov $KEY, %ecx
mov $STDIN, %ebx
mov $SYSREAD, %eax
int $SYSCALL
mov %eax, KEY_LEN # dlugosc klucza
xor %edx, %edx
movb KEY, %dl
sub $'A', %edx
add $1, %edx
mov $WYBOR_LEN, %ebx
cmp $'0' , %bl
je LOOP1
#cmp $'1' , %bl
jne LOOP2
#szyfr cezara
#klucz w edx
LOOP1:
mov $0, %ecx # licznik petli
sub $1, TEXT_LEN
ENCRYPTION_LOOP:
mov TEXT(, %ecx, 1), %eax #przesuwamy aktualny znak do rejestru al
cmp $'A', %al
jb DONT_ENCRYPT_CHAR
cmp $'z', %al
ja DONT_ENCRYPT_CHAR
cmp $'Z', %al
jna ENCRYPT_CHAR
cmp $'a', %al
jb DONT_ENCRYPT_CHAR
ENCRYPT_CHAR:
add %edx, %eax
cmp $'z', %al
jae CORRECT_CHAR_CODE
cmp $'a', %al
jae CHAR_CODE_OK
cmp $'Z', %al
ja CORRECT_CHAR_CODE
jmp CHAR_CODE_OK
CORRECT_CHAR_CODE:
sub $26, %al
CHAR_CODE_OK:
movb %al, TEXT(, %ecx, 1)
DONT_ENCRYPT_CHAR:
add $1, %ecx # inkrementacja licznika petli
cmp %ecx, TEXT_LEN
jne ENCRYPTION_LOOP
add $1, TEXT_LEN
jmp WYSWIETL
LOOP2:
mov $0, %ecx # licznik petli
sub $1, TEXT_LEN
DECRYPTION_LOOP:
mov TEXT(, %ecx, 1), %eax #przesuwamy aktualny znak do rejestru al
cmp $'A', %al
jb DONT_DECRYPT_CHAR
cmp $'z', %al
ja DONT_DECRYPT_CHAR
cmp $'Z', %al
jna DECRYPT_CHAR
cmp $'a', %al
jb DONT_DECRYPT_CHAR
DECRYPT_CHAR:
sub %edx, %eax
cmp $'A', %al
jb CORRECT_CHAR_CODE2
cmp $'Z', %al
jbe CHAR_CODE_OK2
cmp $'a', %al
jb CORRECT_CHAR_CODE2
jmp CHAR_CODE_OK2
ja CORRECT_CHAR_CODE2
jmp CHAR_CODE_OK2
CORRECT_CHAR_CODE2:
add $26, %al
CHAR_CODE_OK2:
movb %al, TEXT(, %ecx, 1)
DONT_DECRYPT_CHAR:
add $1, %ecx # inkrementacja licznika petli
cmp %ecx, TEXT_LEN
jne DECRYPTION_LOOP
add $1, TEXT_LEN
jmp WYSWIETL
WYSWIETL:
#wyswietlanie tekstu
mov TEXT_LEN, %edx
mov $TEXT, %ecx
mov $STDOUT, %ebx
mov $SYSWRITE, %eax
int $SYSCALL
EXIT:
# zakonczenie programu
mov $EXIT_SUCCESS, %ebx
mov $SYSEXIT, %eax
int $SYSCALL
答案 0 :(得分:1)
这里有一些错误:
#wczytywanie klucza
mov $KEY_MAXLEN, %edx
mov $KEY, %ecx
mov $STDIN, %ebx
mov $SYSREAD, %eax
int $SYSCALL
mov %eax, KEY_LEN # dlugosc klucza
xor %edx, %edx
movb KEY, %dl
sub $'A', %edx
add $1, %edx
mov $WYBOR_LEN, %ebx ; ebx = number of characters
cmp $'0' , %bl ; bl = and(0xff, number of characters)
je LOOP1
cmp $'1' , %bl ; bl = and(0xff, number of characters)
# jne LOOP2 ; this should be je LOOP2, not jne LOOP2
#szyfr cezara
#klucz w edx
LOOP1:
您不会比较密钥,而是$WYBOR_LEN
,因为:
mov $WYBOR_LEN, %ebx
然后,即使偶然bl
不是'0'
(0x30
)或'1'
(0x31
),您也没有任何错误 - 处理,所以代码继续到LOOP1
。
要修复错误,你可以这样做:
xor %edx, %edx
movb KEY, %dl
sub $'A', %edx
add $1, %edx
movb KEY, %bl ; store the value from KEY to bl before comparison.
cmp $'0' , %bl
je LOOP1
cmp $'1' , %bl
je LOOP2
; print here some message to inform user that the input is invalid.
jmp _start
#szyfr cezara
#klucz w edx
LOOP1: