На этом шаге мы перечислим основные строковые команды и рассмотрим команду MOVS.
Практически все языки программирования содержат команды обработки строк. Ассемблер имеет следующие команды обработки символьной информации:
Эти команды можно "настроить" на обработку байта или слова. Для этого после служебного слова указывается буква B (байт) или W (слово), например: MOVSB или MOVSW. Если для команды MOVS наличие операндов обязательно, то для команд MOVSB и MOVSW они могут отсутствовать. Эти команды предполагают, что регистры DI и SI содержат относительные адреса, указывающие на необходимые области памяти (для их загрузки можно использовать команду LEA). Регистр SI обычно связан с регистром сегмента данных - DS:SI. Регистр DI всегда связан с регистром дополнительного сегмента - ES:DI. Следовательно, команды MOVS, STOS, CMPS и SCAS требуют инициализации регистра ES.
Каждая из перечисленных команд может иметь префикс REP, который позволяет этим командам обрабатывать строки любой длины. Префикс кодируется непосредственно перед цепочечной командой, например:
REP MOVSB.
Для использования префикса REP необходимо установить количество повторений в регистре CX. При выполнении цепочечной команды с префиксом REP происходит уменьшение на 1 значения в регистре CX до нуля. Таким образом, можно обрабатывать строки любой длины.
Флаг направления определяет направление повторяющейся операции:
. . . START DB 10 DUP('*') END_S DB 10 DUP(' ') . . . CLD ;Сброс флага DF. MOV CX,10 ;Счетчик на 10 байт. LEA DI,END_S ;Адрес области "куда". LEA SI,START ;Адрес области "откуда". REP MOVSB ;Переслать данные. . . .
Для области, принимающей строку, сегментным регистром, является регистр ES, а регистр DI содержит относительный адрес области, принимающий строку. Для области, передающей строку, сегментным регистром является регистр DS, а регистр SI содержит относительный адрес. Таким образом, в начале программы перед выполнением команды MOVS необходимо инициализировать регистр ES вместе с регистром DS, а также загрузить требуемые относительные адреса полей в регистры DI и SI. В зависимости от состояния флага DF команда MOVS производит увеличение или уменьшение на 1 (для байта) или на 2 (для слова) содержимого регистров DI и SI.
Приведем команды, эквивалентные цепочечной команде REP MOVSB:
LABEL1: JCXZ LABEL2 ;Переход, если CX=0. MOV AL,[SI] MOV [DI],AL INC/DEC DI ;Инкремент или декремент. INC/DEC SI ;Инкремент или декремент. LOOP LABEL1 LABEL2: . . .
При использовании команд MOVSB или MOVSW Ассемблер предполагает наличие корректной длины строковых данных и не требует кодирования операндов в команде. Для команды MOVS длина должна быть закодирована в операндах. Например, если поля FLDA и FLDB определены как байтовые (DB), то команда
REP MOVS FLDA,FLDB
предполагает повторяющуюся пересылку байтов из поля FLDB в поле FLDA. Эту команду можно записать также в следующем виде:
REP MOVS ES:BYTE PTR[DI], DS:[SI].
Однако загрузка регистров DI и SI адресами FLDA и FLDB обязательна в любом случае.
На следующем шаге мы рассмотрим команду загрузки строки.