1

Caesar 暗号に関するコードに問題があります。コメントを英語に変更するつもりはありませんが、とにかくたいしたものではありません。プログラムは2つのプログラムから構成されています。1 つはシーザー暗号をコーディングし、2 つ目はシーザー暗号を解読しました。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
4

1 に答える 1

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'0x31LOOP1

バグを修正するには、次のようにします。

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:
于 2013-03-10T23:43:08.193 に答える