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

на главную

Жанры

Ассемблер для процессоров 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
Процедуры на языке ассемблера

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

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

Черный Маг Императора 13

Герда Александр
13. Черный маг императора
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 13

Последняя Арена 4

Греков Сергей
4. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 4

Маяк надежды

Кас Маркус
5. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Маяк надежды

Великий перелом

Ланцов Михаил Алексеевич
2. Фрунзе
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Великий перелом

Сопротивляйся мне

Вечная Ольга
3. Порочная власть
Любовные романы:
современные любовные романы
эро литература
6.00
рейтинг книги
Сопротивляйся мне

Инквизитор Тьмы 2

Шмаков Алексей Семенович
2. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы 2

Мастер Разума V

Кронос Александр
5. Мастер Разума
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Мастер Разума V

Бандит 2

Щепетнов Евгений Владимирович
2. Петр Синельников
Фантастика:
боевая фантастика
5.73
рейтинг книги
Бандит 2

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Падение Твердыни

Распопов Дмитрий Викторович
6. Венецианский купец
Фантастика:
попаданцы
альтернативная история
5.33
рейтинг книги
Падение Твердыни

"Дальние горизонты. Дух". Компиляция. Книги 1-25

Усманов Хайдарали
Собрание сочинений
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Дальние горизонты. Дух. Компиляция. Книги 1-25

Ох уж этот Мин Джин Хо 2

Кронос Александр
2. Мин Джин Хо
Фантастика:
попаданцы
5.00
рейтинг книги
Ох уж этот Мин Джин Хо 2

Энфис 6

Кронос Александр
6. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 6