Книги
чёрным по белому
Главное меню
Главная О нас Добавить материал Поиск по сайту Карта книг Карта сайта
Книги
Археология Архитектура Бизнес Биология Ветеринария Военная промышленность География Геология Гороскоп Дизайн Журналы Инженерия Информационные ресурсы Искусство История Компьютерная литература Криптология Кулинария Культура Лингвистика Математика Медицина Менеджмент Металлургия Минералогия Музыка Научная литература Нумизматика Образование Охота Педагогика Политика Промышленные производства Психология Путеводители Религия Рыбалка Садоводство Саморазвитие Семиотика Социология Спорт Столярное дело Строительство Техника Туризм Фантастика Физика Футурология Химия Художественная литература Экология Экономика Электроника Энергетика Этика Юриспруденция
Новые книги
Цуканов Б.И. "Время в психике человека" (Медицина)

Суворов С. "Танк Т-64. Первенец танков 2-го поколения " (Военная промышленность)

Нестеров В.А. "Основы проэктирования ракет класса воздух- воздух и авиационных катапульных установок для них" (Военная промышленность)

Фогль Б. "101 вопрос, который задала бы ваша кошка своему ветеринару если бы умела говорить" (Ветеринария)

Яблоков Н.П. "Криминалистика" (Юриспруденция)
Реклама

Использование ассемблера для оптимизации программ на С++ - Магда Ю.С.

Магда Ю.С. Использование ассемблера для оптимизации программ на С++ — БХВ-Петербург , 2004. — 496 c.
ISBN 5-94157-414-2
Скачать (прямая ссылка): ispolzovaniyaassemblera2004.djvu
Предыдущая << 1 .. 27 28 29 30 31 32 < 33 > 34 35 36 37 38 39 .. 127 >> Следующая

#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
char sl[] = "string must be converted to upper"; int lsl = strlen(sl);
102
Часть I. Основы эффективного программирования на ассемблере
printf("Before: %s\n", si);
_asm {
lea ESI,. DWORD PTR si
mov ECX, DWORD PTR lsl
next:
mov AL, BYTE PTR [ESI] cnp AL, 'a'
jb next_addr
cmp AL, 'z'
j a next_addr
and AL, Odfh
mov BYTE PTR [ESI], AL next_addr:
inc ESI
loop next
}
printf("After: %s\n", si); getchar(); return 0;
}
Преобразование символов к верхнему регистру выполняется в ассемблерном блоке. Перед началом преобразования загружаем в регистр esi адрес строки si, а в регистр есх — ее размер lsl. Поскольку мы имеем дело с литерами, то анализ выполняется для символов 'a'-'z', не затрагивая остальные. Алгоритм преобразования реализован в. следующем фрагменте программного кода:
next:
mov AL, BYTE PTR [ESI]
cmp AL, 'a*
jb next_addr
спр AL, 1z1
ja next_addr
and AL, Odfh
mov BYTE PTR [ESI], AL
next_addr:
inc ESI
loop next
Гпава 2. Оптимизация вычислительных алгоритмов с помощью ассемблера______103_
Окно работающего приложения изображено на рис. 2.13.
Рис. 2.13. Окно приложения, преобразующего символы нижнего регистра строки в символы верхнего регистра
Чтобы у читателя не сложилось впечатление, будто операции со строками можно эффективно выполнять только используя строковые команды, я приведу пример программы, где нет ни одной строковой команды. Операции над строками можно успешно выполнять и при помощи обычных команд ассемблера. Исходный текст консольного приложения для сравнения двух строк (листинг 2.22) демонстрирует такой подход.
// CMP_STRINGS_WITHOUT_PRIMITIVES.срр : Defines the entry point for the // console application.
ttinclude "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
char sl[] = "string 1"; char s2[] = "stRing 1";
bool result;
printf("String 1: %s\n", si); printf("String 2: %s\n", s2);
_asm {
lea ESI, DWORD PTR si //' адрес строки si lea EDI, DWORD PTR s2 // адрес строки s2 again:
mov AL, BYTE PTR [ESI]
104
Часть I. Основы эффективного программирования на ассемблере
mov DL, BYTE PTR [EDI] push EAX push EDX xor AL, DL pop EDX pop EAX jz streq jmp strnot_eq streq:
test AL, DL j z succ inc ESI inc EDI jmp again strnot_eq:
mov EAX, 0 jmp quit
succ:
mov EAX, 1
quit:
mov DWORD PTR result, EAX };
'if (result)
printf("Equal\n") ;
else
printf("Not equal\n"); getchar(); return 0;
}
В ассемблерном блоке адрес строки-источи и ка помещается в регистр esi. а адрес строки-приемника — в регистр edi. Элементы строк помещаются в регистры al и dl, после чего сравнивается их содержимое:
mov AL, BYTE PTR [ESI] mov DL, BYTE PTR [EDI] push EAX push EDX xor AL, DL
Гпава 2. Оптимизация вычислительных алгоритмов с помощью ассемблера
105
pop EDX pop ЕАХ jz streq jmp strnot_eq
Если символы не равны, то происходит выход из процедуры с возвратом 0 в основную программу. Если процедура обнаруживает равенство символов, то они проверяются на равенство 0 (команда перехода jz streq):
streq;
test AL, DL
jz succ
inc ESI
inc EDI
jmp again
Если элементы равны 0, то очевидно, что достигнут конец строки, и сравнение прошло успешно, т. е. строки равны. В этом случае в переменной result возвращается значение 1. Если же элементы не равны 0 (хотя и равны между собой), то выполняется переход на следующие адреса в строках, и цикл сравнения повторяется.
С помощью команд
push ЕАХ push EDX xor AL, DL pop EDX pop EAX
достигается дополнительный эффект оптимизации. Дело в том, что процессоры Pentium (включая последние модели), содержат кэш команд и данных размером по 8 или 16 килобайт каждый, известные под названием "кэш первого уровня" (level one cache). С точки зрения производительности программы, имеет чрезвычайно важное значение, чтобы критические участки кода размещались в кэше' команд. Очень желательно уменьшить размер кода — это позволит выполнять условные ветвления и циклические вычисления большей вложенности в кэше команд, что значительно увеличивает производительность работы приложения.
Применение коротких инструкций позволяет разместить большую часть кода в кэше команд. В нашем случае однобайтовые команды push reg и pop
106
Часть I. Основы эффективного программирования на ассемблере
reg уменьшают размер программного кода, что для вычислений с большой вложенностью оказывается весьма актуальным.
В нашем случае строки не равны, поэтому в окно работающего приложения (рис. 2.14) будет выведено соответствующее сообщение.
В щ
Рис. 2.14. Окно приложений, выполняющего операцию сравнения двух строк
Как видим, при манипуляциях со строками можно обходиться и без специализированных команд, однако код получается несколько громоздким за счет дополнительных операций инкремента-декремента адресов и дополнительного анализа условий равенства символов и конца строк. Самая высокая скорость выполнения строковых операций достигается обычно при копировании одной строки в другую или при перемещении элементов строки из одной области памяти в другую. Это особенно заметно при перемещении больших объемов данных.
Предыдущая << 1 .. 27 28 29 30 31 32 < 33 > 34 35 36 37 38 39 .. 127 >> Следующая