Я хочу написать алгоритм TEA на сборке 8086 (TASM), и я застрял на первых шагах разделения переменной открытого текста (блока) на 2 переменные и ключа на 4 переменные (k1, k2, k3, k4).
Я знаю, что предел открытого текста (блока) составляет 64 бита (8 байт)
и предел ключа составляет 128 бит (16 байт).
Переменная открытого текста хранится в разделе данных:
plainText db 8 dup('$')
и это две переменные открытого текста:
p1 db 4 dup('$')
p2 db 4 dup('$')
Ключевая переменная хранится следующим образом:
key db 16 dup("$")
и 4 разделенные клавиши:
k0 db ?
k1 db ?
k2 db ?
k3 db ?
Это мой текущий раздел шифрования для приема входных данных от пользователя:
proc encryptionSelection
print plainTextPrompt
inputString [plainText] ; Block Limit: 64 bits -> 8 bytes
call printLine
print p1
call printLine
print p2
print keyPrompt
inputString [key] ; Key Limit: 128 bits -> 16 bytes
; Encryption Logic Here...
ret
endp encryptionSelection
macro inputString storage
pusha
mov ah, 0ah
lea dx, storage
int 21h
popa
endm inputString
macro print value
pusha
mov ah, 09h
mov dx, offset value
int 21h
popa
endm print
Я пробовал много способов и много гуглил, но не смог найти решения.
Вы неправильно используете функцию int 21h 0Ah. Требуется буфер со специальной настройкой; первый байт указывает длину буфера (исключая первые два байта), а второй байт должен быть инициализирован нулем и будет установлен DOS равным количеству текстовых байтов, фактически отправленных пользователем. Эти данные начинаются с третьего байта буфера. Размер вашего буфера должен вмещать достаточно места для желаемых данных в виде текста, а также завершающего возврата каретки, размещенного DOS. См. список прерываний fd.lod.bz/rbil/interrup/dos_kernel/210a.html#2602
и 4 разделенные клавиши:
k0 db ? k1 db ? k2 db ? k3 db ?
Ключ имеет 16 байт, поэтому, разделенный на 4, я ожидаю, что это будут двойные слова, а не байты!
plainText db 8 dup('$') p1 db 4 dup('$') p2 db 4 dup('$')
Ваш макрос inputString использует функцию DOS.BufferedInput 0Ah, и вы не предоставляете DOS правильный буфер! См. Как работает буферизованный ввод.
Правильное определение обычного текста будет следующим:
plainText db 9, 0, 9 dup('$')
p1 db 4 dup('$')
p2 db 4 dup('$')
Один из способов разделить введенные 8 байтов — скопировать следующим образом:
print plainTextPrompt
inputString [plainText] ; Block Limit: 64 bits -> 8 bytes
mov di, offset p1
mov si, offset plainText+2
mov cx, 8
rep movsb
Но наиболее эффективным способом было бы реорганизовать буферы:
plainText db 9, 0
p1 dd 0 ;;
p2 dd 0 ; Together 9 bytes of inputbuffer
db 0 ;;
db 0 ; 1 extra byte for word-alignment
key db 17, 0
k0 dd 0 ;;
k1 dd 0 ;;;
k3 dd 0 ; Together 17 bytes of inputbuffer
k4 dd 0 ;;;
db 0 ;;
db 0 ; 1 extra byte for word-alignment
Тогда копирование не потребуется, и вы сможете легко получить доступ к отдельным переменным.
На самом деле нет смысла что-либо разделять, вы можете просто проиндексировать свой
plainText
. Но если вы настаиваете, вы, конечно, можете скопировать его, например.mov ax, plainText; mov dx, plainText + 2; mov p1, ax; mov p1 + 2, dx;
(повторитеp2
сplainText + 4
иplainText + 6
).