Учебники

Сборка — Струны

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

  • Явно хранит длину строки
  • Использование часового персонажа

Мы можем хранить длину строки явно, используя символ счетчика $ 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 уменьшается до нуля.