Статьи по Assembler

       

Зачем нужен ассемблер - дополнение Геннадия Майко


Читайте также:

  • статью "Зачем он нужен, этот ассемблер?"
  • обсуждение статьи с MemoBreaker'ом

Если вы уже прочитали статью Зачем он нужен, этот ассемблер? и ее обсуждение с MemoBreaker'ом, то должны помнить, что речь там идет о том, имеет или нет смысл писать на ассемблере прикладные программы для Windows. И если этот вопрос (без сомнения, важный для некоторой маргинальной части программистского поголовья, к которой причисляем себя и мы), по-прежнему остается без ответа, то сопряженный с ним вопрос "А имеет ли смысл писать на ассемблере системные программы" особых сомнений ни у кого не вызвал. Все участники обсуждения время от времени делали реверансы в сторону драйверов устройств, обработчиков потоков данных и т.п., говоря, что, дескать, вот в них-то ого-го, йэх, ну и ну, ух ты, то есть ассемблеру самое и место. Никаких более веских аргументов, правда, привести не пытались, но консенсуса достигли.

С радостью сообщаем, что по-настоящему веские аргументы у нас теперь есть благодаря Геннадию Майко, его опыту разработчика и его письму, которое мы публикуем здесь с согласия автора и с большой благодарностью. Опыта Геннадия в разработке на самом нижнем уровне системы, на стыке с оборудованием, вполне достаточно, чтобы люди, способные воспринимать авторитетные мнения, сделали для себя правильные выводы.

Добрый день!

Прочитав вновь поднятую тему "о нужности" ассемблера, хотел бы добавить свои личные комментарии.

1. На мой взгляд, использование ассемблера полезно и оправдано в качестве "дополнения" к используемому (выбранному, навязанному) языку или среде програмирования. Я бы еще раз хотел подчеркнуть – дополнение, а не противопоставление.

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

- Микросхема MPEG-encoder'a выдавала поток данных не в такой последовательности, как было принято для данного процессора (проще говоря, порядок байт был big-endian, а не little-endian). В этом случае одна команда BSWAP рассматривалась как одна из 3-х других алтернатив вот такому, на мой взгляд, некрасивому решению, которое предлагалось на С или С++:

*ptData = ((*ptData & 0xFF) << 24) | ((*ptData & 0xFF00) << 8) | ((*ptData & 0xFF0000) >> 8) | ((*ptData & 0xFF000000) >> 24);

- Эта же микросхема генерировала длинную последовательность нулей в конце MPEG-потока данных, за сигнатурой, соответствующей окончанию этого потока. Эти нули необходимо было исключить. Использование команды SCASD также рассматривалось в качестве одной из 2-х альтернатив простейшего линейного поиска.

- В приложении и библиотеках программы для управления платой MPEG-encoder'a, написанной для Windows NT4, очень широко и успешно использовалась функция InterlockedExchangeAdd (по сути, на ней базировалось вся синхронизация взаимной работы нескольких потоков). При переносе этой программы под Windows 95 оказалось, что там этой функции нет (!). Реализация собственной функции с таким же названием и синтаксисом, написанной на ассемблере с использованием команды XADD, рассматривалась в качестве основной альтернативы полной переработки всего кода синхронизации.

Для себя я сделал вывод, что ассемблер является одним из вспомогательных инструментов разработки программ. Знание его не является обязательным, но оно желательно, так как это есть еще одна "степень свободы" при решении программистских задач.



2. Я знаю, по крайней мере, несколько микросхем, которые являются "micro-code driven". То есть внутри есть несколько очень специализированных процессоров, для которых необходимо писать программы. Здесь применение языка ассемблера весьма оправдано. Я знаю, по крайней мере, одну попытку написания и использования компилятора языка С для таких микросхем, которая (естественно) завершилась неудачей. Срок "жизни" такой микросхемы весьма недолог для того, чтобы разрабатывать, поддерживать и использовать какой-то язык высокого уровня при ее программировании.

Я понимаю, что это не имеет явного отношения к программированию на ассемблере для X86 и пример не очень соответствует обсуждаемой теме, но, по крайней мере, слово "ассемблер" в нем присутствует :)

3. Несколько комментариев к высказаным в статье областям применения ассемблера:

> - на нем удобно писать такие вещи как VxD драйвера (не знаю возможно ли это на С++)

Мне приходилось писать драйвера и на ассемблере, и на С, и на С++. Как по мне, так их "удобнее" писать на С++, но это дело вкуса и "религии".

Я могу (по памяти) привести некоторую информацию об этих проектах. Все они были написаны "с нуля" (from the scratch). Она может быть полезна при сравнении использования ассемблера и языков высокого уровня.

- Драйвер и библиотека (DLL) для специализированной платы (8 контроллеров RS-232/485, таймер, контроллер клавиатуры, несколько вспомогательных регистров), языки: asm для драйвера, С для библиотеки. Операционная система Windows 3.11/95. Система "задышала" через 6 месяцев, еще 9 месяцев система модернизировалась (были изменения в "железе" и требованиях к функциональности).

- Драйвер, библиотека и приложения для платы MPEG-encoder'a, языки: С для драйвера, С++ для библиотеки и приложения. Операционная система Windows NT4. Система "задышала" через 4 месяца, еще 2 месяца ушло на "доводку". При изменении "железа" адаптация занимала пару недель.

- Драйвер, библиотека и приложения для другой платы MPEG-encoder'a, языки: С++ для драйвера, библиотеки и приложения. Операционная система Windows NT4/2000. Система "задышала" через 3 месяца, еще 1 месяц ушел на "доводку". Драйвер изначально поддерживал работу с несколькими функционально однотипными платами и в нем использовалось и наследование, и абстрактные классы, и виртуальные функции, и статические элементы классов, т.е. практически полный набор методов ООП.

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

>- ассемблер используется в критичных к скорости выполнения программах

> (можно, конечно, и INLINE, но как сами говорили "можно и отверткой в ухе...")

Я думаю, что MPEG-encoder является "критичной к скорости выполнения" программой и она действительно требует очень много времени (например, 3 платы MPEG-encoder'ов (установленных на одном компьютере), в которых мультиплексирование аудио- и видео-данных проводилось в программе, а не в микросхеме, при одновременной работе занимали более 75 % времени работы процессоров). Но у нас не возникало даже идеи переписать все это на ассемблере! Я думаю, причина этого – требуемые очень большие временнЫе ресурсы разработки. Система просто не успела бы выйти на рынок; с другой стороны, предложения типа "поставьте мощный компьютер" не вызывали у клиентов никаких возражений.

А вот где ассемблер действительно, по моему, нужен, так это в "недрах" операционной системы (например, при переключении задач), где может потребоваться использование специальных команд процессора, которых нет в языках программирования высокого уровня.


Еще раз резюмируем сказанное специально для тех, до кого авторитетные мнения доходят с трудом:

  • Наиболее рационально сегодня применять ассемблер в качестве весьма ограниченного оптимизирующего дополнения к современным мощным языкам более высокого уровня, позволяющего использовать особенности процессорной архитектуры, недоступные в этих языках.
  • Ассемблерным языкам по-прежнему есть и останется место в микропроцессорной технике на уровне программирования чипов.
  • Практически нет никаких специальных причин писать на ассемблере не только приложения Windows, но и драйверы, то есть в отношении драйверов действительны те же самые соображения, что и в отношении приложений, в том числе и п.1.
  • Единственное место, где необходимость применения ассемблера неоспорима и безусловна - это самые нижние уровни ядра операционных систем.


  • Мы на 100% согласны с этими выводами, и поэтому, как раз сейчас приступая к новому прикладному проекту, уже окончательно определились с базовым языком. Конечно же, это будет ассемблер.


    Содержание раздела