Невозможно отучить людей изучать самые ненужные предметы.
Введение в CSS
Преимущества стилей
Добавления стилей
Типы носителей
Базовый синтаксис
Значения стилевых свойств
Селекторы тегов
Классы
CSS3
Надо знать обо всем понемножку, но все о немногом.
Идентификаторы
Контекстные селекторы
Соседние селекторы
Дочерние селекторы
Селекторы атрибутов
Универсальный селектор
Псевдоклассы
Псевдоэлементы
Кто умеет, тот делает. Кто не умеет, тот учит. Кто не умеет учить - становится деканом. (Т. Мартин)
Группирование
Наследование
Каскадирование
Валидация
Идентификаторы и классы
Написание эффективного кода
Вёрстка
Изображения
Текст
Цвет
Линии и рамки
Углы
Списки
Ссылки
Дизайны сайтов
Формы
Таблицы
CSS3
HTML5
Блог для вебмастеров
Новости мира Интернет
Сайтостроение
Ремонт и советы
Все новости
Справочник от А до Я
HTML, CSS, JavaScript
Афоризмы о учёбе
Статьи об афоризмах
Все Афоризмы
Помогли мы вам |
Надеюсь, ты знаешь книгу Стивена Леви «Хакеры: герои компьютерной революции». Если нет, обязательно прочти! Сейчас мы с тобой поностальгируем по тем славным временам, которые описывает Леви. В частности, вспомним, чем пионеры хакерства занимались в «Клубе моделирования железной дороги» Массачусетского технологического института и как они кодили.
Хакеры тех времен, корпя над своими программами, пытались выжать из ассемблерных инструкций все, что только возможно, чтобы в итоге программа стала максимально компактной. Попытки отрезать часть инструкций от компьютерной программы без воздействия на конечный результат стали для хакеров навязчивой идеей.
Иногда такая резьба по ассемблерному коду принимала состязательный характер — своеобразное соревнование мачо, призванное доказать себе и другим, что совершенству нет предела. Ты отрезал две инструкции или даже одну? Получи бурные аплодисменты братьев по духу. Ты пересмотрел проблему с нуля, с неожиданного угла зрения и разработал новый алгоритм, который сократил программу на целый блок команд? Испытай катарсис и получи еще более бурные аплодисменты!
Особое рвение хакеры проявляли к оптимизации подпрограммы для печати десятичных чисел. За несколько месяцев они изготовили целую кучу вариаций. С чего вдруг такой интерес именно к этой задаче?
С того, что в MIT действовало негласное правило: «Если ты собственноручно написал подпрограмму печати десятичных чисел, значит, знаешь о компьютере достаточно, чтобы называть себя в некотором роде программистом. Причем, если у тебя ушло на эту подпрограмму около сотни ассемблерных инструкций, значит, ты беспроглядный глупец, хотя и программист. А если написал действительно хорошую и короткую процедуру меньшего размера, то можешь попробовать называть себя хакером».
В конечном счете, попеременно убирая инструкции то в одном, то в другом месте, хакеры допилили процедуру печати десятичных чисел до пятидесяти с небольшим инструкций.
Дальше дело приняло серьезный оборот. Поиск лучшего решения превратился в нечто большее, чем просто состязание, — в поиск святого Грааля. Однако, сколько бы сил ни было потрачено, никому не удавалось преодолеть барьер из пятидесяти команд. И когда практически все уже смирились с тем, что это невозможно, один из хакеров догадался посмотреть на решение задачи под другим углом. В итоге его версия подпрограммы уместилась в 46 ассемблерных инструкций.
До этого знаменательного часа все считали, что оптимальный алгоритм для подпрограммы печати десятичных чисел — это последовательное вычитание, при котором использовались таблицы степеней числа 10. Однако, как оказалось, задачу можно решить и без такой таблицы. Леви, к сожалению, не приводит ассемблерный код в своей книге, поэтому познакомиться с этим шедевром у нас не получится.
Но не спеши расстраиваться. Сейчас я покажу тебе свою версию такой подпрограммы. Она у меня уместилась в 12 инструкций (и 23 байта).
Кому-то может показаться, что столько заморачиваться ради того, чтобы сократить размер программы, в наши дни уже не имеет смысла. Однако такой навык очень пригождается, когда пишешь какой-нибудь шелл-код или редактируешь скомпилированный бинарник. И в том и в другом случае нужно уметь обходиться как можно меньшим количеством ассемблерных инструкций. И сейчас я покажу несколько трюков, которые помогут тебе сокращать размер своих ассемблерных программ.
Во всех предыдущих уроках мы читали память, ссылаясь на нужную нам ячейку через регистр BX
. Примерно вот так.
Но то же самое можно сделать и вот так.
Инструкция lodsb
говорит процессору 8088: «Загрузи байт из адреса, на который указывает DS:
, и сохрани этот байт в регистр AL
. И затем увеличь SI
на единицу (если флаг направления сброшен в 0)».
Еще у 8088 есть инструкция lodsw
, которая работает почти как lodsb
, только загружает из DS:
слово (сдвоенный байт), сохраняет результат в регистр AX
и увеличивает SI
на 2.
Зная о существовании инструкций lodsb
/lodsw
и их противоположностей stosb
/stows
, мы можем написать подпрограмму для копирования области памяти.
Этот внутренний цикл занимает всего четыре байта. Но у процессора 8088 есть инструкции movsb
и movsw
, которые делают ту же самую операцию, но при этом не используют регистр AL
или AX
.
Теперь внутренний цикл занимает три байта. Но и это не предел! Мы можем сделать все то же самое без инструкции loop
.
Обрати внимание, что movsb
— это две инструкции в одной: lodsb
и stosb
. И аналогично в movsw
скомбинированы lodsw
и stosw
. При этом movsb
/movsw
не используют регистры AL
/AX
, что весьма приятно.
|
|