Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Assembler (Уч_пос_Лаб_Ч1).doc
Скачиваний:
5
Добавлен:
01.04.2025
Размер:
1 Мб
Скачать
☆

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

aldst

axdst

eaxdst

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 ;Сравнивать, пока {CX0 и 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>.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]