
10.12. Пример программы.
Текст для шифрования вводится в командной строке. В тексте — только прописные латинские буквы и пробелы. Удалить пробелы и зашифровать текст. Каждый символ преобразуется по формуле 3*код+5 (mod 26). При этом считается, что код буквы 'A' равен 0, код буквы 'B' равен 1 и т.д. В программе должны быть одна или две подпрограммы для шифрования символа (или группы символов).
файл z.asm
COMMENT &
Текст для шифрования вводится в командной строке. В тексте — только прописные латинские буквы и пробелы. Удалить пробелы и зашифровать текст. Каждый символ преобразуется по формуле 3*код+5 (mod 26). При этом считается, что код буквы 'A' равен 0, код буквы 'B' равен 1 и т.д.
&
.MODEL small
.STACK 100h
.DATA
text DB 83 DUP(?)
msg1 DB "В командной строке нет текста", 0Dh, 0Ah, '$'
msg2 DB "В тексте недопустимые символы", 0Dh, 0Ah, '$'
.CODE
;---------------------------------------------------
; Подпрограмма шифровки символа
; Вход: AL - код символа
; Выход: AL - код зашифрованного символа
;----------------------------------------------------
encode PROC
cmp al,'A' ; Если код символа не ниже кода 'A'
jnae cf1
cmp al,'Z' ; и не выше кода 'Z',
jnbe cf1
sub al,'A' ; Получить код символа, начиная с 0
;
; Вычисление нового кода по формуле 3*код+5 (mod 26)
mov bl,3
mul bl
add ax,5
mov bl,26
idiv bl
add ah,'A' ; Вернуться к коду ASCII
mov al,ah
clc ; нормальное завершение
ret
cf1: stc ; на входе символ, отличный от прописной латинской буквы
ret
encode ENDP
start: mov ax, @data
mov ds, ax
; Копирование цифр из хвоста командной строки в строку для обработки
mov cx, 0
mov cl, es:[80h] ; Длина хвоста командной строки в CX
jcxz empty ; Если хвост пустой – на empty
dec cx ; Не нужно учитывать начальный пробел
mov si, 82h ; Смещение хвоста – в SI
mov di, OFFSET text ; Указатель для новой строки – в DI
; Цикл обработки элементов строки
n: mov al, es:[si] ; Очередной символ хвоста – в AL
cmp al, ' ' ; Если встретился пробел,
je cont ; то пропустить его,
call encode ; а символ - зашифровать
jc no_A_Z ; Переход, если встретился недопустимый символ
mov [di],al ; Поместить зашифрованный символ в строку-приемник
inc di ; Переместить указатель в строке-приемнике
cont: inc si ; Переместить указатель в исходной строке
loop n
;
; Поместить в строку-приемник символы ВК и ПС, а также терминатор
mov word ptr [di], 0A0Dh
inc di
inc di
mov byte ptr [di], '$'
; Вывод итоговой строки на экран
mov dx, OFFSET text
mov ah, 9h
int 21h
jmp short fin
; Вывод сообщений об ошибках
empty: mov dx, OFFSET msg1 ; строка пуста
mov ah, 9h
int 21h
jmp short fin
no_A_Z: mov dx, OFFSET msg2 ; в строке недопустимые символы
mov ah, 9h
int 21h
; Завершение работы программы
fin: mov ax, 4C00h
int 21h
END start
Распечатка этого файла составляет содержание отчета. Текст программы обязательно должен включать подробные комментарии.
Отметим некоторые особенности в тексте программы.
1. Программа открывается блоком комментариев, начинающихся с директивы COMMENT. Сами комментарии должны ограничиваться парой одинаковых символов. В нашем случае выбран &, так как этот символ не встречается внутри самих комментариев.
2. Директивы Ассемблера (PROC, DB и т.д.) и операции времени трансляции (OFFSET) выделяем прописными буквами для лучшей читабельности текста программы.
3. Вместо числовых кодов букв (например 41h) используем их символьные обозначения ('A').
Трансляция программы
tasm/zi/l z
(ключ /zi — включение отладочной информации, /l — получение файла листинга). На выходе файлы z.obj и z.lst.
Компоновка
tlink /v z
(ключ /v — включение отладочной информации). На выходе файлы z.exe и z.map.
Запуск на выполнение
D:\>z
В командной строке нет текста
D:\>z Aa1
В тексте недопустимые символы
D:\>z NEW LINE
SRTMDSR
Отладка
D:\>td z.exe NEW LINE
(расширение .exe нужно обязательно указывать).
Закроем окна Module (Alt+F3) и Watch (Alt+F3). Создадим окно CPU (F10/View/CPU). Распахнем его (F5). Последовательными нажатиями Ctrl+M добъемся, чтобы в панели кода отображались и строки исходного текста программы и сгенерированный код:
#z#start: start: mov ax, @data
cs:001E B82A57 mov ax,572A
Мы видим, что встроенная переменная Ассемблера @data на этапе выполнения получила значение 572Ah.
Перейдем в панель данных (Shift+Tab). Отобразим хвост командной строки (Alt+F10/Goto/80).
Уменьшим размер окна CPU и отобразим окно данных (F10/View/Dump), расположив его ниже окна CPU. В окне Dump перейдем к адресу text (Alt+F10/Goto/text). Обратите внимание, теперь мы набираем не конкретный адрес, а его символическое обозначение.
Переходим в окно CPU (F6). Выполняем программу по шагам, чтобы проследить правильность ее выполнения. (Никогда не запускайте программу на языке Ассемблера сразу на выполнение! Наверняка в ней есть ошибки.) Для этого нажимаем F7, если нужно войти в подпрограмму, или F8, если подпрограмму нужно выполнить как одну команду.
Проследите, как изменяется содержимое стека при вызове подпрограммы и возврате в главную программу.
Посмотреть вывод на экран зашифрованной строки можно, нажав комбинацию Alt+F5. "Вернуться обратно" — также Alt+F5.
Если мы хотим испытать работу программы с другими исходными данными, нет необходимости выходить из отладчика и заново вызывать его. В главном меню: F10/Run/Arguments. Появляется диалоговое окно Enter command line arguments. Введем, например, WEB (начальный пробел вводить не нужно, он появится автоматически). Отладчик задает вопрос: Reload program so arguments take effect? (Заново загрузить программу, чтобы аргументы возымели эффект?). Разумеется, отвечаем Yes (нажимаем Enter). Чтобы в панели кода перейти к первой команде нашей программы, набираем Ctrl+G/ start (опять-таки обратите внимание: мы набираем не адрес, а его символическое имя).
Выход из отладчика — Alt+X.
Для проверки правильности самих вычислений нам поможет отладчик. Вычислим с помощью отладчика, в какой символ перейдет буква 'N'. Для этого откроем окно Watches (F10/View/Watches) и введем в него выражение:
(('N'-'A')*3+5) mod 26d+'A',c
Здесь после запятой указан символ форматирования c, являющийся сокращением от слова character — символ. В окне появится выражение и результат его вычисления:
(('T'-'A')*3+5) mod 26d+'A',c 'S'
Обратите внимание на суффикс d у числа 26. При отладке программы на языке Ассемблера числа по умолчанию рассматриваются отладчиком как 16-ричные.
Для выполнения таких же вычислений с буквой 'E' выделите уже введенное выражение и в контекстном меню выберите пункт Edit (редактирование).