Форум программистов, компьютерный форум, киберфорум
Assembler, MASM, TASM
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.63/2256: Рейтинг темы: голосов - 2256, средняя оценка - 4.63
Ушел с форума
Автор FAQ
 Аватар для Mikl___
16374 / 7686 / 1080
Регистрация: 11.11.2010
Сообщений: 13,761
18.12.2013, 13:34  [ТС]
ГЛАВА 17
СТРОКОВЫЕ КОМАНДЫ
(часть 1/2)

Одно из важных применений компьютеров связано с обработкой текстов, которое представляет собой манипуляции последовательностями байт, содержащих коды символов — символьными строками. При разработке редакторов текста или программы форматирования текста требуются программы пересылок и сравнения символьных строк, введения строк в другие строки или удаления строк из других строк. Часто необходимо отыскивать в строке заданную подстроку или заменять подстроку другой подстрокой. Редактор текста требуется в любой вычислительной системе широкого назначения, и его возможности, улучшающие операции системы над символьными строками, имеют большое значение. Рассмотрим те возможности микропроцессоров x86, которые упрощают обработку строк.
Хотя большинство приводимых команд ориентированы на операции с символьными строками, их можно применять и для других целей, например, в файловой системе для поиска в массивах ключей. Эти команды не выполняют функции, которые невозможно реализовать другими командами; они предназначены только для более эффективного выполнения некоторых действий, которые потенциально оказываются весьма длительными (например, поиск заданных байта, слова или подстроки в строке или массиве, содержащем тысячи байт).
Строковые команды требуются при переходе от одной системы кодирования к другой (от ASCII к EBCDIC или Unicode), строковые команды так же необходимы в системах шифрования и дешифровки.
У строковых команд много общего, поэтому, чтобы не повторяться, сначала подробно рассмотрим одну из них, а затем коротко опишем остальные.
ASCII — American Standard Code for Information Interchange — американский стандартный код для обмена информацией. Стандартная схема кодирования знаков, веденная в 1963 и широко используемая во многих машинах.
EBCDIC — Extended Binary Coded Decimal Interchange Code — расширенный двоично-десятичный код для обмена информацией. 8-битный код для кодирования знаков, в основном используемый в вычислительных машинах фирмы IBM.
Unicode — Стандарт Unicode был предложен некоммерческой организацией Unicode Consortium, образованной в 1991 г. Для представления каждого символа в этом стандарте используются два байта, что позволяет закодировать очень большое число символов из разных письменностей: в документах Unicode могут соседствовать русские, латинские, греческие буквы, китайские иероглифы и математические символы.
Команды сравнения строк CMPSB/W/D/Q
(Сравнение строк, состоящих из байтов/слов/двойных слов =
"COMPARE Strings Byte/Word/Double/Quadruple word operands")
В строковых командах под строкой понимается не только последовательность байт (символов), но и последовательность слов, а также двойных и четверных слов. Поэтому каждая строковая операция может быть представлена четырьмя командами: одни предназначены для обработки строк из байтов, другие — для обработки строк из слов, третьи — для двойных слов и четвертые — для учетверенных. В языке ассемблера мнемокоды этих команд различаются тем, что в первом случае указывается буква B (byte), в другом — буква W (word), в третьем — D (double word), в четвертом — Q (quadruple word). Например, в командах сравнения строк (CMPS, compare strings) используются следующие мнемокоды:
Синтаксис команд:
CMPS <операнд1>,< операнд2>
CMPSB
CMPSW
CMPSD
CMPSQ

В целом действия этих команд совпадают, поэтому обычно про них говорят как про одну команду CMPS, и только если надо, уточняют, какой вариант ее имелся в виду
Семантика команды: сравнение двух последовательностей (цепочек) элементов в памяти.
Алгоритм работы:
  • выполнить вычитание элементов (<операнд2> -<операнд1>), адреса элементов предварительно должны быть загружены:
    • адрес операнда1 — в пару регистров DS:ESI/SI;
    • адрес операнда2 — в пару регистров ES:EDI/DI;
  • в зависимости от состояния флага DF изменить значение регистров ESI/SI и EDI/DI:
    • если DF=0, то увеличить содержимое этих регистров на длину элемента последовательности;
    • если DF=1, то уменьшить содержимое этих регистров на длину элемента последовательности;
    Таблица 17.1.1
     DF=0 DF=1
    CMPSB +1 -1
    CMPSW +2 -2
    CMPSD +4 -4
    CMPSQ +8 -8
  • в зависимости от результата вычитания установить флаги:
    • если очередные элементы цепочек не равны, то CF=1, ZF=0;
    • если очередные элементы цепочек или цепочки в целом равны, то CF=0, ZF=1;
  • при наличии префикса выполнить определяемые им действия (см. команды REPE/REPNE).
Применение: у команды два операнда, но их местоположение заранее известно, поэтому они явно не указываются. Команда без префиксов осуществляет простое сравнение двух элементов в памяти. Размеры сравниваемых элементов зависят от применяемой команды. Команда CMPS может работать с элементами размером в байт, слово, двойное слово. В качестве операндов в команде указываются идентификаторы последовательностей этих элементов в памяти. Реально эти идентификаторы используются лишь для получения типов элементов последовательностей, а их адреса должны быть предварительно загружены в указанные выше пары регистров. Транслятор, обработав команду CMPS и выяснив тип операндов, генерирует одну из машинных команд CMPSB, CMPSW или CMPSD. Абсолютный адрес операнда1 из первой строки по умолчанию должен задаваться регистрами DS:SI/ESI, а абсолютный адрес операнда2 из второй строки должен задаваться регистрами ES: DI/EDI.
Причем для операнда2 обязательно должен использоваться регистр ES, а для адресации операнда1 можно делать замену сегмента с использованием соответствующего префикса.
Основное действие команды CMPS заключается в сравнении элемента одной строки с элементом другой строки. Это сравнение выполняется так же, как и в команде CMP, то есть путем вычитания операндов без записи куда-либо полученной разности, команда CMPS так же меняет значения регистров SI/ESI и DI/EDI и меняет их так, чтобы в них оказались адреса соседних элементов строк. В зависимости от текущего значения флага направления DF: при DF=0 значения регистров увеличиваются — происходит переход вперед к следующим элементам, а при DF=1 значения регистров уменьшаются — происходит переход назад к предыдущим элементам.
Сам по себе флаг DF не меняется, его должен менять автор программы командами CLD (очистка флага DF) и STD (установка флага DF). По команде CLD флаг направления сбрасывается (DF=0), а по команде STD — устанавливается (DF=1).
Для того чтобы эти команды можно было использовать для сравнения последовательности элементов, имеющих размерность байт, слово, двойное слово, необходимо использовать один из префиксов REPE или REPNE. Префикс REPE заставляет циклически выполняться команды сравнения до тех пор, пока содержимое регистра ECX/CX не станет равным нулю или пока не совпадут очередные сравниваемые элементы цепочек (флаг ZF=1). Префикс REPNE заставляет циклически производить сравнение до тех пор, пока не будет достигнут конец цепочки (ECX/CX=0) либо не встретятся различающиеся элементы цепочек (флаг ZF=0).
Допустим Вам необходимо сравнить пароль, вводимый с клавиатуры, с паролем находящимся где-то в памяти:
Assembler
1
2
3
4
5
6
7
8
9
10
11
PASSWORD db ‘fyfcnfcbz’,0Dh ;строка символов пароля
;плюс 0Dh код, генерируемый клавиатурой при нажатии 
;на клавишу «Enter»
MOV ECX,10 ;количество символов в пароле
XOR EBX,EBX ;позиционируемся на первый символ
A1: MOV AH,0 ;получение очередного символа
INT 16h ;из буфера клавиатуры в регистр AL
CMP AL,PASSWORD[EBX];сравнение с очередным символом
JNE EXIT ;если не совпал символ — выход из программы
INC EBX ;переход на следующий символ
LOOP A1 ;продолжаем сравнение
При использовании команды CMPS и префикса повторения REPE программа изменится следующим образом:
Assembler
1
2
3
4
5
6
7
8
9
10
PASSWORD DB 'fyfcnfcbz',0Dh ;Строка для сравнения
BUFFER_KLAV DB 50 DUP (?) ;буфер клавиатуры
CLD ;просмотр строки в направлении возрастания адресов
MOV ECX,10 ;длина цепочки
MOV ESI,OFFSET PASSWORD ;в DS:ESI адрес пароля
MOV EDI,BUFFER_KLAV ;в ES:EDI адрес буфера клавиатуры
REPE CMPSB ;сравнивать, пока равны, если не конец
JNZ M1 ; строки, то встретились разные элементы
;действия, если элементы строки совпали
M1: ;действия, если элементы строки не совпали
Команды загрузки строки LODSB/W/D/Q
(Загрузка строки, состоящей из байтов/слов/двойных слов =
"LOAD String Byte/Word/Double/Quadruple word operands")
Синтаксис команд:
LODS <операнд>
LODSB
LODSW
LODSD
LODSQ

Семантика команды: загрузка элемента из операнда в регистр-аккумулятор AL/AX/EAX.
Алгоритм работы:
  • загрузить элемент из ячейки памяти, адресуемой парой DS:ESI/SI, в регистр AL/AX/EAX. Размер элемента задается неявно (для команды LODS определяется по размерности операнда) или явно в соответствии с применяемой командой (для команд LODSB, LODSW, LODSD);
  • изменить значение регистра SI/ESI на величину, равную длине элемента цепочки. Знак этой величины зависит от состояния флага DF:
    • DF=0 — значение положительное, то есть просмотр от начала цепочки к ее концу;
    • DF=1 — значение отрицательное, то есть просмотр от конца цепочки к ее началу.
Применение: команды извлекают элемент из ячейки памяти в один из регистров. Перед командой LODS можно указать префикс повторения REP, но в этом нет особого смысла, так как обычно эту команду используют в некотором цикле для просмотра некоторой цепочки с элементами фиксированного размера:
Assembler
1
2
3
4
STR DB · · · ;строка данных STR
CLD ;будем двигаться от начала строки к ее концу
LEA SI,STR ;загружаем в регистр SI адрес строки STR
LODSB ;загрузить первый байт из STR в AL
Команды сохранения строки STOSB/W/D/Q
(Сохранение строки байтов/слов/двойных слов =”STORE String Byte/Word/Double/Quadruple word operands”)
Синтаксис команд:
STOS <операнд>
STOSB
STOSW
STOSD
STOSQ

Семантика команды: сохранение элемента из регистра-аккумулятора AL/AX/EAX в последовательности (цепочке) операндов.
Алгоритм работы:
  • записать элемент из регистра AL/AX/EAX в ячейку памяти, адресуемую парой ES: DI/EDI. Размер элемента задается неявно (для команды STOS определяется из размерности операнда) или конкретной применяемой командой (для команд STOSB, STOSW, STOSD);
  • изменить значение регистра DI на величину, равную длине элемента цепочки. Знак этого изменения зависит от состояния флага DF:
    • DF=0 — увеличить, что означает просмотр от начала цепочки к ее концу;
    • DF=1 — уменьшить, что означает просмотр от конца цепочки к ее началу.
Применение: команды сохраняют элемент из регистров AL/AX/EAX в ячейку памяти. Перед командой STOS можно указать префикс повторения REP, в этом случае появляется возможность работы с блоками памяти, заполняя их значениями в соответствии с содержимым регистра ECX/CX:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
;заполнить область памяти STR пробелами
STR db 'Какая-то строка'
LEN_STR=$-STR ;вычисляем длину строки STR
CLD ;двигаемся от начала строки STR
MOV AL,' ' ;поместим в регистр AL символ пробела
LEA DI,STR ;поместим в DI адрес начала STR
MOV CX,LEN_STR ;поместим в CX длину STR
REP STOSB ;заполняем пробелами строку STR
;пример совместной работы STOSB и LODSB: копировать одну
; строку в другую до первого пробела
STR1 db 'Какая-то строка'
LEN_STR1=$-STR
STR2 DB LEN_STR1 DUP (' ')
CLD
MOV CX,LEN_STR1
LEA SI,STR1
LEA DI,STR2
M1: LODSB
CMP AL,' '
JC EXIT ;выход, если пробел
STOSB
LOOP M1
EXIT:
Команды пересылки строк MOVSB/W/D/Q
(Пересылка строк байтов/слов/двойных/учетверенных слов =
MOVE String Byte/Word/Double/Quadruple word”)
Синтаксис команд:
MOVS <операнд1>,<операнд2>
MOVSB
MOVSW
MOVSD
MOVSQ

Семантика команды: пересылка элементов из последовательности (цепочки) операнд1 в последовательность (цепочку) операнд2.
Алгоритм работы:
  • выполнить копирование байта, слова, двойного или учетверенного слова из операнда2 в операнд1, при этом адреса элементов предварительно должны быть загружены:
    • адрес операнда2 — в пару регистров DS:ESI/SI (DS по умолчанию, допускается замена сегмента);
    • адрес операнда1 — в пару регистров ES:EDI/DI (замена сегмента не допускается);
  • в зависимости от состояния флага DF изменить значение регистров ESI/SI и EDI/DI:
    • если DF=0, то увеличить содержимое этих регистров на длину структурного элемента последовательности;
    • если DF=1, то уменьшить содержимое этих регистров на длину структурного элемента последовательности;
  • если есть префикс повторения, то выполнить определяемые им действия.
Применение: команды пересылают элемент из одной ячейки памяти в другую. Размеры пересылаемых элементов зависят от применяемой команды. Команда MOVS может работать с элементами размером в байт, слово, двойное, учетверенное слово. В качестве операндов в команде указываются идентификаторы последовательностей этих элементов в памяти. Реально эти идентификаторы используются лишь для получения типов элементов последовательностей, а их адреса должны быть предварительно загружены в указанные выше пары регистров. Транслятор, обработав команду MOVS и выяснив тип операндов, генерирует одну из машинных команд MOVSB, MOVSW, MOVSD или MOVSQ. Для адресации операнд1 обязательно должен использоваться регистр ES.
Для того чтобы эти команды можно было использовать для пересылки последовательности элементов, имеющих размерность байт, слово, двойное, учетверенное слово, необходимо использовать префикс REP. Префикс REP заставляет циклически выполняться команды пересылки до тех пор, пока содержимое регистра ECX/CX не станет равным нулю:
Assembler
1
2
3
4
5
6
7
8
9
10
STR1 DB 'STR1 копируется в STR2'
LEN_STR1=$-STR1
A_STR1 DD STR1
STR2 DB LEN_STR1 DUP (' ')
A_STR2 DD STR2
MOV CX,LEN_STR1
LDS SI,STR1
LES DI,STR2
CLD
REP MOVSB
Пару команд LODS и STOS можно использовать вместо команды MOVS, если вам требуется примитивное шифрование или дешифровка данных. Наиболее часто используемый фрагмент пригоден как для шифрования, так и для дешифровки.
Assembler
1
2
3
4
V1: LODSD ;грузим в EAX
NOT EAX ;или XOR EAX,0F3D4B90Ah или ROR EAX,3;шифруем
STOSD ;пересылаем в память
LOOP V1
Текст получается зашифрованным от простого просмотра, но его криптостойкость равна нулю, если его захотят дешифровать.
Команды сканирования строк SCASB/W/D/Q
(Сканирование строки байтов/слов/двойных/учетверенных слов =
SCAN String Byte/Word/Double/Quadruple word”)
Синтаксис команд:
SCAS <операнд>
SCASB
SCASW
SCASD
SCASQ

Семантика команды: поиск значения в последовательности (цепочке) элементов операнда в памяти.
Алгоритм работы:
  • выполнить вычитание (элемент цепочки <операнд>—(EAX/AX/AL)).
  • Элемент цепочки <операнд> локализуется парой ES:EDI/DI. Замена сегмента ES не допускается;
  • по результату вычитания установить флаги;
  • изменить значение регистра EDI/DI на величину, равную длине элемента цепочки. Знак этой величины зависит от состояния флага DF:
    • DF=0 — величина положительная, то есть просмотр от начала цепочки к ее концу;
    • DF=1 — величина отрицательная, то есть просмотр от конца цепочки к ее началу.
Применение: команды сканирования сравнивают значение в регистре EAX/AX/AL с ячейкой памяти, локализуемой парой регистров ES:EDI/DI.
Размер сравниваемого элемента зависит от применяемой команды.
Команда SCAS может работать с элементами размером в байт, слово или двойное слово. В качестве операнда в команде указывается идентификатор последовательности элементов в памяти. Реально этот идентификатор используется лишь для получения типа элементов последовательности, а ее адрес должен быть предварительно загружен в указанную выше пару регистров. Транслятор, обработав команду SCAS и выяснив тип операндов, генерирует одну из машинных команд: SCASB, SCASW или SCASD. Для адресации операнда обязательно должен использоваться регистр ES.
Для того чтобы эту команду можно было использовать для поиска значения в последовательности элементов, имеющих размерность байт, слово или двойное слово, необходимо использовать один из префиксов REPE или REPNE. Эти префиксы не только заставляют циклически выполняться команду поиска, пока https://www.cyberforum.ru/cgi-bin/latex.cgi?ECX/CX\neq 0, но и отслеживают состояние флага ZF:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
STR DB '...' ;сосчитаем число пробелов в строке STR
LEN_STR=$-STR ;вычислим длину строки
LEA DI,STR ;адрес начала строки в DI
MOV CX,LEN_STR ;длину строки — в CX
MOV AL,' ' ;в AL символ, который ищем
MOV BX,0 ;счетчик для подсчета пробелов в строке
CLD ;считаем от начала строки
CYCL: REPE SCASB ;переход на EXIT, если цепочка просмотрена
JCXZ EXIT ;полностью
INC BX ;нашли пробел — увеличим счетчик пробелов
JMP CYCL ;в начало цикла
EXIT:
0
Закрытая тема Создать тему
Новые блоги и статьи
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы ## О чём эта статья В процессе построения ОДУ-модели (система дифференциальных. . .
сукцессия 24. Промежуточное общее описание модели
anaschu 12.07.2026
Хендофф: модель АМ→ЭКМ сукцессии микоризы (ризосфера, 50 лет) Содержание проекта Симуляция вековой (50 лет) экологической сукцессии в почве леса Основные участники: АМ-гриб, ЭКМ-гриб,. . .
сукцессия 23. Более физиологичная физиология, более экологичная экология, более диффурные диффуры.
anaschu 12.07.2026
Что реально нашли и починили за эти 5 часов Правило Линдемана (КПД конверсии сахара в тело, kEff) — раньше 100% полученного углерода шло прямо в биомассу гриба; теперь только kEff=0. 5 (после. . .
сукцессия 22. От артефактов к физиологии: калибровка агентной модели грибной сукцессии для воспроизведения сезонной динамики и pH-плато
anaschu 11.07.2026
Аннотация В данной работе представлена калибровка агентной модели динамики грибных сообществ (fungal-succession), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru