2013-03-10 70 views
1

我的代碼有關凱撒密碼的問題。我不會將我的評論改爲英文,但它們並不多。該計劃由兩個程序組成。一個是編碼凱撒密碼,另一個是解碼凱撒密碼。我是這樣做的,當我按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 

回答

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: