Мы уже использовали строки переменной длины в наших предыдущих примерах. Строки переменной длины могут содержать столько символов, сколько необходимо. Как правило, мы указываем длину строки одним из двух способов —
- Явно хранит длину строки
- Использование часового персонажа
Мы можем хранить длину строки явно, используя символ счетчика $ location, который представляет текущее значение счетчика местоположений. В следующем примере —
msg db 'Hello, world!',0xa ;our dear string len equ $ - msg ;length of our dear string
$ указывает на байт после последнего символа строковой переменной msg . Следовательно, $ -msg дает длину строки. Мы также можем написать
msg db 'Hello, world!',0xa ;our dear string len equ 13 ;length of our dear string
В качестве альтернативы, вы можете хранить строки с последующим символом часового, чтобы разделить строку, вместо того, чтобы явно хранить длину строки. Стражный символ должен быть специальным символом, который не появляется в строке.
Например —
message DB 'I am loving it!', 0
Строковые Инструкции
Каждая строковая инструкция может требовать исходного операнда, целевого операнда или обоих. Для 32-битных сегментов строковые инструкции используют регистры ESI и EDI для указания на операнды источника и назначения соответственно.
Однако для 16-битных сегментов регистры SI и DI используются для указания на источник и пункт назначения соответственно.
Существует пять основных инструкций для обработки строк. Они —
-
MOVS — эта инструкция перемещает 1 байт, слово или двойное слово данных из ячейки памяти в другую.
-
LODS — эта инструкция загружается из памяти. Если операнд имеет один байт, он загружается в регистр AL, если операнд — одно слово, он загружается в регистр AX и двойное слово загружается в регистр EAX.
-
STOS — эта инструкция сохраняет данные из регистра (AL, AX или EAX) в памяти.
-
CMPS — эта инструкция сравнивает два элемента данных в памяти. Данные могут иметь размер в байтах, слово или двойное слово.
-
SCAS — эта инструкция сравнивает содержимое регистра (AL, AX или EAX) с содержимым элемента в памяти.
MOVS — эта инструкция перемещает 1 байт, слово или двойное слово данных из ячейки памяти в другую.
LODS — эта инструкция загружается из памяти. Если операнд имеет один байт, он загружается в регистр AL, если операнд — одно слово, он загружается в регистр AX и двойное слово загружается в регистр EAX.
STOS — эта инструкция сохраняет данные из регистра (AL, AX или EAX) в памяти.
CMPS — эта инструкция сравнивает два элемента данных в памяти. Данные могут иметь размер в байтах, слово или двойное слово.
SCAS — эта инструкция сравнивает содержимое регистра (AL, AX или EAX) с содержимым элемента в памяти.
Каждая из вышеприведенных инструкций имеет версию байта, слова и двойного слова, а строковые инструкции могут повторяться с использованием префикса повторения.
В этих инструкциях используется пара регистров 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.
В следующей таблице представлены различные версии строковых инструкций и предполагаемое пространство операндов.
Основная инструкция | Операнды в | Байт Операция | Слово Операция | Операция двойного слова |
---|---|---|---|---|
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 |
Повторяющиеся префиксы
Префикс REP, если он установлен перед строковой инструкцией, например — REP MOVSB, вызывает повторение инструкции на основе счетчика, размещенного в регистре CX. REP выполняет инструкцию, уменьшает CX на 1 и проверяет, равен ли CX нулю. Он повторяет обработку инструкций, пока CX не станет равным нулю.
Флаг направления (DF) определяет направление операции.
- Используйте CLD (сбросить флаг направления, DF = 0), чтобы выполнить операцию слева направо.
- Используйте STD (Установить флаг направления, DF = 1), чтобы выполнить операцию справа налево.
Префикс REP также имеет следующие варианты:
РЭП: Это безусловное повторение. Он повторяет операцию, пока CX не станет равным нулю.
REPE или REPZ: это условное повторение. Он повторяет операцию, в то время как нулевой флаг указывает на равенство / ноль Он останавливается, когда ZF указывает не равно / ноль или когда CX равен нулю.
REPNE или REPNZ: это также условное повторение. Он повторяет операцию, в то время как нулевой флаг указывает не равно / ноль. Он останавливается, когда ZF указывает на равенство / ноль или когда CX уменьшается до нуля.