- •В.А. Афанасьев
- •Часть 1 Лабораторный практикум
- •Предисловие
- •1. Краткая характеристика операционной среды ms-dos в компьютерах с операционной системой Windows
- •2. Составные части ms-dos и её инициализация
- •3. Взаимодействие Ассемблерной программы с ms-dos и аппаратными средствами Компьютера
- •4. Сегментированная организация памяти в реальном режиме. Виды памяти в среде ms-dos
- •Распределение первого мегабайта памяти компьютера
- •Содержание некоторых полей области данных bios
- •5. Программная модель 32-разрядных процессоров i80x86
- •Назначения сегментных регистров
- •6.2.2. Путь выполнения команды
- •6.2.3. Трансляция программы. Опции командной строки
- •6.2.4. Структура программы для .Exe- и .Com-файлов. Образ программы в памяти
- •Сегменты упрощенной модели памяти Small
- •%Title "Имя exe-файла программы"
- •%Title "Имя com – файла программы"
- •6.2.5. Работа с отладчиком Turbo Debugger (td)
- •6.2.6. Форматы машинных команд и их кодирование
- •Определение эффективного адреса
- •Косвенные виды адресации
- •6.2.6.2. Использование 32-битных регистров
- •6.2.7. Работа над синтаксическими ошибками при ассемблировании программы
- •6.3. Задание к работе. Порядок выполнения
- •6.4. Контрольные вопросы
- •Приложения к лабораторной работе № 1 п.1.1. Машинные коды команд базового процессора i8086
- •Машинные коды команд базового процессора i8086
- •П.1.2. Демонстрационные файлы
- •П.1.3. Форматы исполняемых файлов .Exe и .Com на диске
- •А) Листинг prog_com. Lst
- •Содержимое префикса программы psp
- •А) Листинг prog_exe.Lst
- •Б) Машинный код исполняемого файла prog_exe.Exe на диске объёмом 624 байта
- •Формат заголовка исполняемого .Exe – файла на диске
- •7.2.2. Ввод с клавиатуры символьной информации
- •7.2.2.1. Буфер ввода данных с клавиатуры
- •7.2.2.2. Системные функции dos ввода данных с клавиатуры
- •Сравнительная характеристика функций dos ввода с клавиатуры
- •7.2.3. Функции dos вывода данных на экран
- •7.2.4. Расширенные коды ascii и управление программой с клавиатуры
- •Расширенные коды для функциональных клавиш
- •7.2.5. Строковые команды. Общая характеристика
- •Команды обработки строк
- •7.3. Задания к работе. Подготовка и выполнение
- •7.4. Контрольные вопросы
- •Приложения к лабораторной работе № 2 Приложение п.2.1. Примеры реализаций типового задания
- •Приложение п.2.2. Esc-последовательности
- •Параметры Esc-последовательности
- •Приложение п.2.3. Таблица символов в кодировке ascii
- •8.2.2. Прямое программирование видеобуфера в текстовом режиме
- •8.2.3. Справочные данные по функциям bios
- •8.2.3.1. Прерывание int 10h. Видеофункции bios
- •Текстовые видеорежимы и страницы в стандарте vga, поддерживаемые современными видеоконтроллерами
- •8.2.3.2. Рекомендации по использованию видеосервиса bios
- •8.2.3.3. Прерывание int 16h
- •8.2.3.4. Задержка программных операций
- •Int 15h, функция 86h
- •8.3. Варианты индивидуального задания
- •8.4. Контрольные вопросы
- •Приложения к работе № 3 Примеры реализаций типовых заданий п.3.1. Листинг 3.4. Программа получения скан-кодов клавиш клавиатуры
- •П.3.2. Листинг 3.5. Демонстрационная программа использования функций bios для работы с экраном и клавиатурой
- •9.2.1. Представление знаковых и беззнаковых чисел в 16-разрядном компьютере
- •Представление чисел в 16- разрядном компьютере
- •9.2.2. Преобразование ascii-кодов чисел с произвольным основанием в двоичное число
- •9.2.3. Преобразование двоичного числа в ascii-строку числа по произвольному основанию
- •9.2.4. Задание к работе. Порядок выполнения
- •Варианты заданий 1-7
- •Варианты заданий 8-14
- •9.2.5. Вопросы построения многомодульных программ
- •9.2.6. Ассемблирование и компоновка отдельных модулей в программу. Создание библиотеки объектных модулей
- •9.3. Контрольные вопросы
- •Список использованной и рекомендуемой Литературы
- •Оглавление
7.2.5. Строковые команды. Общая характеристика
Строкой или литералом в языке ассемблера называется последовательность букв, цифр и других символов, заключённых в кавычки или апострофы (двойные кавычки). Следует отметить, что иногда понятие строки трактуется в расширительном смысле, а именно, как последовательность байтов, которые могут либо представлять, либо не представлять ASCII-символы.
Строковые команды, несмотря на синонимичное название со строковыми переменными, предназначены для обработки не только ASCII-строк, но и вообще блоков байтов, одинарных или двойных слов, каждое из которых хранится в памяти в двоичном коде.
Строковые команды представлены в табл. 3.1 и по своему назначению делятся на две группы:
команды перемещения данных (Lods, Stos, Movs);
команды для поиска и сравнения данных (Scas, Cmps).
Любая строковая команда может оперировать как байтами, так и словами, что отражается в мнемокоде команды (например: movsb, movsw, movsd). Все строковые команды, в отличие от других команд процессора ix86, используют для выполнения своих функций одни и те же регистры:
ds:si(esi) – регистры строки-источника,
es:di(edi) –регистры строки-приёмника.
Таблица 3.1
Команды обработки строк
Название команды и её мнемокод |
Действие |
Тип исполь-зуемого префикса |
Влияние на флаги |
Lods src – Загрузка Acc из строки src=byte ds:si Lodsb src=word ds:si Lodsw src=dword ds:si Lodsd |
al src ax src eax src |
_ |
Нет |
Stos dst – Сохранение Acc в строке dst=byte es:di Stosb dst=word es:di Stosw dst=dword es:di Stosd |
al dst ax dst eax |
Rep
|
Нет |
Movs dst,src – Пересылка элемента строки dst=byte es:di, src=byte ds:si Movsb dst=word es:di, src=word ds:si Movsw dst=dword es:di, src=dword ds:si Movsd |
dst src |
Rep |
Нет |
Scas dst – Поиск элемента в строке dst=byte es:di Scasb dst=word es:di Scasw dst=dword es:di Scasd |
aldst axdst eaxdst |
Repe Repne
|
Все флаги операции сравнения |
Cmps dst, src – Сравнение элементов строк src=byte ds:si, dst=byte es:di Cmpsb src=word ds:si, dst=word es:di Cmpsw src=dword ds:si, dst=dword es:di Cmpsd |
srcdst !!! |
Repe Repne
|
Все флаги операции сравнения |
При этом индексные регистры si(esi) и di(edi) определяют смещения элементов строк в сегментах данных, определяемых регистрами ds и es соответственно. Установите es = ds, если это не противоречит другим условиям реализации программы, что позволит вам не беспокоиться о корректной адресации сегментов памяти. Необходимо помнить, что в строковых инструкциях приёмник – строка es:di(edi) не допускает переопределение, а источник – строка ds:si(esi), допускает переопределение на es:si(esi).
Каждая из строковых команд выполняет операцию только над парой элементов двух строк (или над одним для команд Lods, Stos, Scas) и автоматически настраивается на обработку соседних элементов, обеспечивая продвижение по строке в нужном направлении, а именно:
si:=si+d, di:=di+d.
Здесь величина d определяется согласно правилу:
Тип операнда Флаг направления
df =0 df =1
byte +1 -1
word +2 -2
dword +4 -4
Префикс повторения, помещённый непосредственно перед строковой командой, заставляет её циклически выполняться определённое число раз до реализации заданного условия. Существуют три командных префикса:
rep (repeat) – повторять, пока cx 0;
repe/repz – повторять, пока (cx 0) (zf = 1);
repne/repnz – повторять, пока (cx 0) (zf = 0).
Префиксы используют регистр CX как счётчик числа циклов (беззнаковое число), которое должно быть записано в cx до начала выполнения строковой команды. Счётчик cx декрементируется на 1 после выполнения строковой команды, но проверяется перед её выполнением. Если cx = 0, то строковая команда не выполняется ни разу. Префиксы repe и repne дополнительно выставляют флаг нуля zf после выполнения строковой операции.
В листинге 2.2. рассматривается использование строковой команды сравнения cmpsb на примере программы с паролем. Идея простейшей защиты программы от несанкционированного запуска заключается в том, что где-то в программе записывается ключевое слово-пароль, и программа, начав работать, требует ввода этого слова с клавиатуры. Если пользователь ввёл пароль правильно, программа продолжит свою работу, иначе попросит ввести его заново или завершится. Ввод пароля обычно осуществляется функцией DOS, не отображающей вводимые символы на экране (обычно 07h или 08h) и заканчивается нажатием клавиши <Enter>.
Листинг 2.2. Фрагмент программы с паролем.
...................
password DB 'camel' ;Пароль
pass_len = $ – password
string DB 80 DUP(?)
promt DB 13,10,'Введите пароль: $'
OK DB 13,10,'Работаем!$'
CODESEG
start: mov ax,@data
mov ds,ax
begin: mov ah,09h ;Вывод запроса на ввод пароля
mov dx,offset promt ;Адрес запроса
int 21h
;Введём пароль
mov bx,0 ;Инициализация индексирования ввода
pass: mov ah,08h ;Функция ввода символа в AL без эха
int 21h
cmp al,13 ;<Enter> ?
je compare ;Да, на сравнение
mov [string+bx],al ;Нет, сохраним символ
mov ah,02
mov dl,'*' ;Запишем на экран *
int 21h
inc bx
jmp pass ;Повторять
;Сравнение введённого пароля с действительным (сравнение строк)
compare: push ds ;Установить ES на сегмент данных
pop es
mov si,offset string ;DS:SI- начало string
mov di,jffset password ;ES:DI- начало password
cld ;DF=0- просмотр вперёд
mov cx,pass_len ;Установить счётчик сравнения
repe cmpsb ;Сравнивать, пока {CX0 и ZF=1} (или повторять
;пока символы двух строк совпадают, но не более CX раз)
jne err ;Строки не равны
Вывод сообщения ОК, подтверждающего правильность пароля
mov ah,09h
mov dx,offset OK
int 21h
;продолжение программы
.................
exit: mov ax,4C00h ;Ввод функции 4С для завершения программы
int 21h
err: jmp begin ;Повторить ввод пароля
END start
Логика построения программы поясняется подробными комментариями. В программе ввод пароля выполняется в бесконечном цикле, поэтому пользователь, не знающий пароля и запустивший программу, для выхода из неё вынужден будет нажать комбинацию клавиш <Ctrl+C>.
