Чтение онлайн

на главную - закладки

Жанры

Ассемблер для процессоров Intel Pentium

Магда Юрий

Шрифт:
 

Листинг 5.12. Модифицированный код листинга 5.11



Разворачивание позволяет наполовину скомпенсировать снижение производительности программы, в которой используется такой цикл. Если оперировать не двумя, а четырьмя двойными словами, то можно развернуть цикл далее.

Приведу еще один пример разворачивания циклов. Пусть имеется массив из 10 целых чисел и требуется присвоить элементам массива с четными номерами значение 0, а элементам с нечетными номерами значение 1. Если особо не задумываться над качеством программы, то можно быстро написать фрагмент программного кода, представленный в листинге 5.13.


Листинг 5.13.

Обработка четных и нечетных элементов целочисленного массива



Данный фрагмент программного кода можно оптимизировать, если обрабатывать в каждой итерации два двойных слова вместо одного. Модифицируем предыдущий пример, поместив программный код в процедуру unrl. Исходный текст измененной программы показан в листинге 5.14.


Листинг 5.14. Модифицированный код листинга 5.13 с разворачиванием цикла



Как видите, исходный текст этого фрагмента кода претерпел существенные изменения по сравнению с предыдущим примером. Программа стала более компактной; повысилась ее производительность, поскольку мы избавились от команд деления и одновременно уменьшили число итераций в два раза.

В каждой итерации обрабатываются одновременно два элемента массива командами

mov DWORD PTR [ESI], 0

mov DWORD PTR [ESI+4],1

В конце каждой итерации содержимое регистра ESI увеличивается на 8 с помощью команды add ESI ,8, указывая на следующую пару элементов. Количество обрабатываемых пар элементов помещается в регистр ЕВХ:

mov EBX, len

shr EBX, 2

dec EBX

Здесь хочу сделать важное замечание. В нашей процедуре обрабатывается 10 двойных слов, поэтому регистр ЕВХ должен содержать значение 9 для корректной работы цикла. Если количество элементов массива будет нечетным, то необходимо обрабатывать последнее двойное слово вне цикла. Это потребует дополнительных команд, но в целом не окажет существенного влияния на быстродействие процедуры, особенно при больших размерах обрабатываемых массивов. Например, чтобы обработать 1589 двойных слов, объединив каждые два элемента, необходимо выполнить 397 итераций для учетверенных слов и после окончания цикла обработать одно двойное слово. При желании читатели могут самостоятельно разработать подобную процедуру, обрабатывающую произвольное количество двойных слов.

Для организации циклических вычислений очень часто используются команда loop и ее модификации. Соответствующие примеры мы рассматривали ранее в этой главе. Эта команда очень удобна, поскольку избавляет программиста от необходимости постоянно проверять условие окончания цикла. Модификации команды loop, такие, например, как loope и loopne, еще больше упрощают программирование циклов.

Несмотря на очевидные удобства в применении, команда loop имеет средние показатели производительности. Если на первое место выходит скорость выполнения программного кода, то команду loop лучше не использовать, особенно при обработке большого числа элементов строк или массивов. В таких случаях желательно заменить команду loop группой команд. Это замечание касается, в первую очередь, приложений, разрабатываемых для процессоров Intel Pentium, поскольку на более ранних процессорах команда loop работает быстрее своих программных аналогов.

Вот пример замены команды loop эквивалентными ей командами:



Что же касается команд loopе и loopпе, то они работают значительно

медленнее, чем эквивалентный им код, включающий обычные команды процессоров Intel Pentium. При очень интенсивных вычислениях команды loopCC (СС = е, ne, z, nz) в программах лучше не использовать. Стандартной эквивалентной замены для таких команд не существует, поскольку в каждом конкретном случае программный код может быть уникальным. Рассмотрим вариант замены команды loopе в приведенном ранее примере 16-разрядного приложения (см. листинг 5.3).

Напомню, что программный код примера выводит на экран строку без начальных символов пробела. В листинге 5.15 показан исходный текст модифицированной программы.

Листинг 5.15. Модифицированный код листинга 5.3



В этой программе команда lооре заменена следующим фрагментом кода (выделен жирным шрифтом):



Как работает эта группа команд? На каждой итерации выполняется поиск символа пробела с помощью команды

сmр byte ptr [SI], AL

Предположим, что обнаружен символ, отличный от пробела. В этом случае команда стр устанавливает флаг ZF в 0. Следующая команда jne $+7 анализирует флаг ZF и передает управление команде, находящейся по адресу со смещением +7 в сегменте программного кода. Это смещение определяется как разность адресов следующей выполняемой команды и текущей. Следующей командой является

mov DX, SI

Она загружает адрес оставшейся части строки в регистр DX для вывода на экран. Эта команда отстоит на 7 байт от выполняемой в данный момент команды. Таким образом, команда jne $+7 передает управление по адресу команды

mov DX, SI

Если обнаруженный символ является пробелом, то выполняется декремент содержимого регистра СХ, и если оно не равно 0, то цикл повторяется. Если строка состоит из одних пробелов, то после окончания цикла управление передается команде

jmp fail

Попробуем теперь подобрать аналог программного кода для команды loopпе, которая используется в программе, отображающей часть строки после знака + (см. листинг 5.4). Исходный текст модифицированной программы представлен в листинге 5.16.

Исходный текст фрагмента кода, используемого вместо команды loopпе, выделен жирным шрифтом. Он очень напоминает программный код из предыдущего примера, с той лишь разницей, что команда jne по смыслу программы заменена командой je, кроме того, изменилась величина смещения (8 вместо 7). Смещение зависит от объема памяти, занимаемого пропускаемыми командами, а в этом фрагменте вместо dec CX используется для разнообразия команда dec CL, занимающая объем памяти на 1 байт больше.


Листинг 5.16. Замена команды loopne в программе из листинга 5.4



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

Глава 6
Процедуры на языке ассемблера

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

Поделиться:
Популярные книги

Кодекс Крови. Книга III

Борзых М.
3. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга III

Отчий дом. Семейная хроника

Чириков Евгений Николаевич
Проза:
классическая проза
5.00
рейтинг книги
Отчий дом. Семейная хроника

Скандальная свадьба

Данич Дина
1. Такие разные свадьбы
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Скандальная свадьба

Путанабус. Трилогия

Старицкий Дмитрий
Фантастика:
боевая фантастика
6.93
рейтинг книги
Путанабус. Трилогия

Идеальный мир для Лекаря 25

Сапфир Олег
25. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 25

Кодекс Крови. Книга ХVI

Борзых М.
16. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХVI

Проданная невеста

Wolf Lita
Любовные романы:
любовно-фантастические романы
5.80
рейтинг книги
Проданная невеста

Потомок бога

Решетов Евгений Валерьевич
1. Локки
Фантастика:
попаданцы
альтернативная история
аниме
сказочная фантастика
5.00
рейтинг книги
Потомок бога

С Д. Том 16

Клеванский Кирилл Сергеевич
16. Сердце дракона
Фантастика:
боевая фантастика
6.94
рейтинг книги
С Д. Том 16

Переиграть войну! Пенталогия

Рыбаков Артем Олегович
Переиграть войну!
Фантастика:
героическая фантастика
альтернативная история
8.25
рейтинг книги
Переиграть войну! Пенталогия

От Советского Информбюро - 1941-1945 (Сборник)

Неизвестен 3 Автор
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
От Советского Информбюро - 1941-1945 (Сборник)

Санек 3

Седой Василий
3. Санек
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Санек 3

Прометей: повелитель стали

Рави Ивар
3. Прометей
Фантастика:
фэнтези
7.05
рейтинг книги
Прометей: повелитель стали

Отмороженный 14.0

Гарцевич Евгений Александрович
14. Отмороженный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Отмороженный 14.0