Ассемблер. Строки

  Светлана Деменева  | 

  Обновл. 8 Дек 2019  | 

 643

В наших предыдущих уроках мы уже использовали строки разной длины.

Строки в Ассемблере

Строки с переменной в качестве длины могут содержать столько символов, сколько необходимо. Как правило, длина строки указывается одним из следующих двух способов:

   явное содержание длины строки;

   использование сигнального символа.

Мы можем явно хранить длину строки, используя символ счётчика местоположения $, который представляет текущее значение счётчика местоположения строки.

Например:

Символ $ указывает на byte после последнего символа строковой переменной msg. Следовательно, $ - msg указывает на длину строки. Мы также можем написать:

В качестве альтернативы, мы можем хранить строки с завершающим сигнальным символом. Сигнальным символом является специальный символ, который не должен находиться внутри строки.

Например:

Строковые инструкции


Каждая строковая инструкция может требовать исходного операнда и операнда назначения. Для 32-битных сегментов строковые инструкции используют регистры ESI и EDI для указания на операнды источника и назначения, соответственно.

Однако, для 16-битных сегментов регистры SI и DI используются для указания на источник и место назначение.

Существует пять основных инструкций для работы со строками в Ассемблере:

   MOVS — эта инструкция перемещает 1 byte, word или doubleword данных из одной ячейки памяти в другую.

   LODS — эта инструкция загружается из памяти. Если операндом является значение типа byte, то оно загружается в регистр AL, если типа word, то оно загружается в регистр AX, если типа doubleword, то оно загружается в регистр EAX.

   STOS — эта инструкция сохраняет данные из регистра (AL, AX или EAX) в память.

   CMPS — эта инструкция сравнивает два элемента данных в памяти. Данные могут быть размера byte, word или doubleword.

   SCAS — эта инструкция сравнивает содержимое регистра (AL, AX или EAX) с содержимым элемента в памяти.

Каждая из инструкций выше имеет версии byte, word или doubleword, а строковые инструкции могут повторяться с использованием префикса повторения.

Эти инструкции используют пару регистров ES:DI и DS:SI, где регистры DI и SI содержат валидные адреса смещения, которые относятся к байтам, хранящимся в памяти. SI обычно ассоциируется с DS (сегмент данных), а DI всегда ассоциируется с ES (дополнительный сегмент).

Регистры DS:SI (или ESI) и ES:DI (или EDI) указывают на операнды источника и назначения, соответственно. Предполагается, что операндом-источником является DS:SI (или ESI), а операндом назначения — ES:DI (или EDI) в памяти.

Для 16-битных адресов используются регистры SI и DI, а для 32-битных адресов используются регистры ESI и EDI.

В следующей таблице представлены различные версии строковых инструкций и предполагаемое место операндов:

Основная инструкция Операнды в: Операция byte Операция word Операция doubleword
MOVS ES:DI, DS:SI MOVSB MOVSW MOVSD
LODS AX, DS:SI LODSB LODSW LODSD
STOS ES:DI, AX STOSB STOSW STOSD
CMPS DS:SI, ES:DI CMPSB CMPSW CMPSD
SCAS ES:DI, AX SCASB SCASW SCASD

Инструкция MOVS

Инструкция MOVS используется для копирования элемента данных (byte, word или doubleword) из исходной строки в строку назначения. Исходная строка указывается с помощью DS:SI, а строка назначения указывается с помощью ES:DI.

Рассмотрим это на практике:

Результат:

Hello, world!

Инструкция LODS


В криптографии шифр Цезаря является одним из самых простых известных методов шифрования. В этом методе каждый символ в открытом тексте заменяется символом, находящимся на некотором постоянном числе позиций левее или правее него в алфавите.

В этом примере давайте зашифруем данные, просто заменив каждую букву алфавита со сдвигом в две буквы, так что A будет заменено на C, B на D и т.д.

Мы используем инструкцию LODS для помещения оригинальной строки password в память:

Результат:

rcuuyqtf

Инструкция STOS

Инструкция STOS копирует элемент данных из регистров AL (для byte — STOSB), AX (для word — STOSW) или EAX (для doubleword — STOSD) в строку назначения, на которую указывает ES:DI в памяти.

В следующем примере мы, с помощью инструкций LODS и STOS, будем конвертировать строки из верхнего регистра в нижний регистр:

Результат:

hello, world

Инструкция CMPS


Инструкция CMPS сравнивает две строки. Эта инструкция сравнивает два элемента данных одного byte, word или doubleword, на которые указывают регистры DS:SI и ES:DI, и устанавливает соответствующие флаги. Вы также можете использовать инструкции прыжков вместе с этой инструкцией.

В следующем примере мы будем сравнивать две строки, используя инструкцию CMPS:

Результат:

Strings are not equal!

Инструкция SCAS

Инструкция SCAS используется для поиска определённого символа или набора символов в строке. Искомый элемент данных должен находиться в регистрах AL (для SCASB), AX (для SCASW) или EAX (для SCASD). Искомая строка должна находиться в памяти и на неё должны указывать ES:DI (или EDI).

Рассмотрим использование инструкции SCAS на практике:

Результат:

found!

Префиксы повторения


Префикс REP, если он установлен перед строковой инструкцией, например, REP MOVSB, вызывает повторение инструкции на основе счётчика, размещённого в регистре CX. REP выполняет инструкцию, уменьшает CX на 1 и проверяет, равен ли CX нулю. Он повторяет обработку инструкций, пока CX не станет равным нулю.

Флаг направления (DF) определяет направление операции:

   Используйте CLD (англ. «Clear Direction Flag» = «Сбросить флаг направления», DF = 0), чтобы выполнить операцию слева направо.

   Используйте STD (англ. «Set Direction Flag» = «Установить флаг направления», DF = 1), чтобы выполнить операцию справа налево.

Префикс REP также имеет следующие вариации:

   REP— это безусловное повторение, которое повторяет операцию, пока CX не станет равным нулю.

   REPE или REPZ — это условное повторение, которое повторяет операцию до тех пор, пока нулевой флаг указывает на равенство/ноль. Он останавливается, когда ZF указывает на неравенство/ноль или, когда CX равен нулю.

   REPNE или REPNZ — это также условное повторение, которое повторяет операцию до тех пор, пока нулевой флаг указывает на неравенство/ноль. Он останавливается, когда ZF указывает на равенство/ноль или, когда CX уменьшается до нуля.

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5
Загрузка...

Добавить комментарий

Ваш E-mail не будет опубликован. Обязательные поля помечены *