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

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

Жанры

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

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

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

Осколки чести

Буджолд Лоис Макмастер
1. Сага о Форкосиганах
Фантастика:
космическая фантастика
9.34
рейтинг книги
Осколки чести

Этика

Гусейнов Абдусалам
Научно-образовательная:
философия
учебники
5.00
рейтинг книги
Этика

Эволюционер из трущоб. Том 10

Панарин Антон
10. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 10

Сборник "Солдат удачи"

Авраменко Александр Михайлович
Фантастика:
боевая фантастика
6.83
рейтинг книги
Сборник Солдат удачи

Последний реанорец. Том X

Павлов Вел
9. Высшая Речь
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний реанорец. Том X

Второгодка. Книга 3. Ученье свет

Ромов Дмитрий
3. Второгодка
Фантастика:
городское фэнтези
сказочная фантастика
альтернативная история
5.00
рейтинг книги
Второгодка. Книга 3. Ученье свет

Битва королей

Мартин Джордж Р.Р.
Фантастика:
фэнтези
5.00
рейтинг книги
Битва королей

Переписка и деловые бумаги

Чехов Антон Павлович
Документальная литература:
публицистика
5.00
рейтинг книги
Переписка и деловые бумаги

Посольство

Уоллер Лесли
Детективы:
политические детективы
5.00
рейтинг книги
Посольство

Англо-русский и русско-английский словарь ПК

Мизинина Ирина
Справочная литература:
словари
6.30
рейтинг книги
Англо-русский и русско-английский словарь ПК

Имперец. Том 1 и Том 2

Романов Михаил Яковлевич
1. Имперец
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Имперец. Том 1 и Том 2

Гримуар темного лорда VI

Грехов Тимофей
6. Гримуар темного лорда
Фантастика:
попаданцы
аниме
фэнтези
5.25
рейтинг книги
Гримуар темного лорда VI

Ворон

LizaMoloko
Фантастика:
попаданцы
фэнтези
гаремник
5.00
рейтинг книги
Ворон

Кентерберийские рассказы

Чосер Джеффри
Старинная литература:
европейская старинная литература
8.00
рейтинг книги
Кентерберийские рассказы