Введение
© Guido Gybels, January-February 2001, All rights reserved.
© Anatoly Podgoretskys, 2002, Authorized Russian Translation.
Вводная глава: Нужно ли это вам?
Многие программисты сегодня ассоциируют ассемблер как сложный, низкоуровневый язык программирования. Они считают его быстрым, но большинство их них думает, что его сложно или невозможно изучить. В действительности, положение не настолько сложно. Вполне возможно научиться писать хороший код, не будучи гением. С другой стороны, не думайте, что несколько уроков позволят вам производить более быстрый код, чем получится с помощью Паскаля. Причина в том, что когда вы пишите на Паскале, то вы на самом деле пользуетесь услугами высокоэффективного программиста – компилятором Дельфи. В целом код производимый им очень эффективный и быстрый. После некоторых уроков по специальным методам кодирования вы сможете сделать более эффективный код, чем Паскаль и Дельфи. Робертом Ли был создан и обслуживается наиболее исчерпывающий сайт по этой теме. Каждый серьезный программист должен познакомиться с информацией на этом сайте.
Большинство программистов считают, что собственный ассемблерный код по определению быстрее, чем скомпилированный компилятором Паскаля. Конечно, так не всегда. Плохо написанные процедуры на Ассемблере могут оказаться по качеству хуже и могут вызвать странные ошибки и проблемы в ваших приложениях. Задачей данных статей не является обучить вас основам Ассемблера. Есть много другой информации в других источниках и конечно вы должны быть в хороших отношениях с системой команд процессоров Intel (в статьях фокус сделан на серию Пентиум, особенно PII и PIII) на уровне обычного программирование. Вы можете найти руководства по семейству процессоров на сайте http://developer.intel.com. И также на сайте (http://webster.cs.ucr.edu/) «The Art of Assembly», очень солидное руководство по программированию на Ассемблере, который должны посмотреть, если хотите заняться серьезным программированием на ассемблере.
В тот момент, когда вы придете к выводу, что ассемблер это нужный вам путь, вы не должны хвататься за него, как за соломинку. Проверьте внимательно свою программу на предмет определения слабых мест. Профилировщик может немного в этом помочь, но лучше обратите особое внимание на структуру и алгоритм. Часто, вы сможете получить лучшие результаты, за счет оптимизации алгоритмов, скорее, чем с помощью ассемблера. С другой стороны, в некоторых особых случаях, таких как манипуляции с битами, ассемблер даст лучший и более простой результат.
Если вы решите, что ассемблер действительно нужен, то потратьте немного времени на планирование вашего кода и алгоритмов. Только после того, как вы будете четко представлять, что вы хотите сделать и как, вы можете приступать к реализации вашей идеи. Если вы не будете об этом думать, то получите кашу из кода, закрученные операторы и трудно управляемую программу.
Для фазы реализации существует несколько обычных правил, которым надо следовать.
Первое важное правило: делайте ваши процедуры как можно короче, ассемблер должен использоваться, только для реально необходимых вещей, в которых важна максимальная производительность. В большинстве случаев делайте это, с помощью простых, но специализированных процедур. Если вы видите, что у вас длинные куски ассемблерного кода в вашем проекте, вы вероятнее всего просто фанат ассемблера.
Второе правило: делайте ваши процедуры читабельными за счет комментирования кода. В связи с линейной структурой ассемблерного кода, каждая отдельная инструкция читается легко сама по себе. Комментарии нужны для объяснения реализации алгоритма, чтобы другие могли понять, что же вы здесь делаете. Не добавляйте комментарии ради самих комментариев. Ваши комментарии должны быть полезны и не избыточны. Например, не делайте подобного:
inc EDX {увеличить значение EDX}Подобный тип комментариев не имеет смысла, поскольку инструкция говорит сама за себя. Комментарии должны описывать внутреннюю работу алгоритма, не дублируя мнемонику команд.
Третье правило: избегайте использования медленных инструкций. В основном должны использоваться простые инструкции вместо сложных агрегатных инструкций, так как последние реализованы с помощью микрокода. Подробное обсуждение этой темы можно найти в работе Agner Fog на сайте http://www.agner.org/assem/. Попробуйте прочитать это несколько раз, глава за главой, пока полностью не поймете основную идею. Это, однако, не означает, что вы не должны их никогда использовать, но это даст вам понимание написания оптимального кода.
И последнее правило: проверяйте свои ассемблерные подпрограммы особенно тщательно. Для подпрограмм, написанных на ассемблере, компилятор делает намного меньше предупреждений и сообщений об ошибках. Особенно будьте внимательны с логическими конструкциями вашего алгоритма. Неиспользуемые переменные и неверное использование указателей не может быть определено так же просто, как и в коде на Паскале. Так, что готовьтесь к интенсивному тестированию и отладке вашего кода. Это потребует больше времени и усилий по сравнению с отладкой Паскаль-кода. Это одна из причин делать процедуры как можно короче и читабельнее.
После этого вступления, мы готовы приступить к реальному изучению предмета. Эти статьи писались с учетом специфики - это означает, большинство информации относится к BASM (сокращение от built-in assembler – встроенный ассемблер) для всех 32-битных версий Дельфи, начиная с третьей. В основном это верно и для Дельфи 2, но это версия сильно устаревшая. Имеется также некоторые проблемы с утечкой памяти для Дельфи 2, и обычно я рекомендую использовать Дельфи версии 3.02 и выше. Если у вас версия 3,4 или 5, то вся информация в данных статьях применима к ним. Если потребуются специфические требования к версии Дельфи, то это будет особо указано.