Как писать на ассемблере в 2018 году



    Статья посвящена языку ассемблер с учетом актуальных реалий. Представлены преимущества и отличия от ЯВУ, произведено небольшое сравнение компиляторов, скрупулёзно собрано значительное количество лучшей тематической литературы.

    1. Язык. Преимущества и отличия от ЯВУ


    Ассемблер (Assembly) — язык программирования, понятия которого отражают архитектуру электронно-вычислительной машины. Язык ассемблера — символьная форма записи машинного кода, использование которого упрощает написание машинных программ. Для одной и той же ЭВМ могут быть разработаны разные языки ассемблера. В отличие от языков высокого уровня абстракции, в котором многие проблемы реализации алгоритмов скрыты от разработчиков, язык ассемблера тесно связан с системой команд микропроцессора. Для идеального микропроцессора, у которого система команд точно соответствует языку программирования, ассемблер вырабатывает по одному машинному коду на каждый оператор языка. На практике для реальных микропроцессоров может потребоваться несколько машинных команд для реализации одного оператора языка.

    Язык ассемблера обеспечивает доступ к регистрам, указание методов адресации и описание операций в терминах команд процессора. Язык ассемблера может содержать средства более высокого уровня абстракции: встроенные и определяемые макрокоманды, соответствующие нескольким машинным командам, автоматический выбор команды в зависимости от типов операндов, средства описания структур данных. Главное достоинство языка ассемблера — «приближенность» к процессору, который является основой используемого программистом компьютера, а главным неудобством — слишком мелкое деление типовых операций, которое большинством пользователей воспринимается с трудом. Однако язык ассемблера в значительно большей степени отражает само функционирование компьютера, чем все остальные языки.

    И хотя драйвера и операционные системы сейчас пишут на Си, но Си при всех его достоинствах — язык высокого уровня абстракции, скрывающий от программиста различные тонкости и нюансы железа, а ассемблер — язык низкого уровня абстракции, прямо отражающий все эти тонкости и нюансы.

    Для успешного использования ассемблера необходимы сразу три вещи:

    • знание синтаксиса транслятора ассемблера, который используется (например, синтаксис MASM, FASM и GAS отличается), назначение директив языка ассемблер (операторов, обрабатываемых транслятором во время трансляции исходного текста программы);
    • понимание машинных инструкций, выполняемых процессором во время работы программы;
    • умение работать с сервисами, предоставляемыми операционной системой — в данном случае это означает знание функций Win32 API. При работе с языками высокого уровня очень часто к API системы программист прямо не обращается; он может даже не подозревать о его существовании, поскольку библиотека языка скрывает от программиста детали, зависящие от конкретной системы. Например, и в Linux, и в Windows, и в любой другой системе в программе на Си/Си++ можно вывести строку на консоль, используя функцию printf() или поток cout, то есть для программиста, использующего эти средства, нет разницы, под какую систему делается программа, хотя реализация этих функций будет разной в разных системах, потому что API систем очень сильно различается. Но если человек пишет на ассемблере, он уже не имеет готовых функций типа printf(), в которых за него продумано, как «общаться» с системой, и должен делать это сам.

    В итоге получается, что для написания даже простой программы на ассемблере требуется весьма большое количество предварительных знаний — «порог вхождения» здесь намного выше, чем для языков высокого уровня.

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

    На языке ассемблера пишут программы или их фрагменты в тех случаях, когда критически важны:

    • объем используемой памяти (программы-загрузчики, встраиваемое программное обеспечение, программы для микроконтроллеров и процессоров с ограниченными ресурсами, вирусы, программные защиты и т.п.);
    • быстродействие (программы, написанные на языке ассемблера выполняются гораздо быстрее, чем программы-аналоги, написанные на языках программирования высокого уровня абстракции. В данном случае быстродействие зависит от понимания того, как работает конкретная модель процессора, реальный конвейер на процессоре, размер кэша, тонкостей работы операционной системы. В результате, программа начинает работать быстрее, но теряет переносимость и универсальность).

    Кроме того, знание языка ассемблера облегчает понимание архитектуры компьютера и работы его аппаратной части, то, чего не может дать знание языков высокого уровня абстракции (ЯВУ). В настоящее время большинство программистов разрабатывает программы в средах быстрого проектирования (Rapid Application Development) когда все необходимые элементы оформления и управления создаются с помощью готовых визуальных компонентов. Это существенно упрощает процесс программирования. Однако, нередко приходится сталкиваться с такими ситуациями, когда наиболее мощное и эффективное функционирование отдельных программных модулей возможно только в случае написания их на языке ассемблера (ассемблерные вставки). В частности, в любой программе, связанной с выполнением многократно повторяющихся циклических процедур, будь это циклы математических вычислений или вывод графических изображений, целесообразно наиболее времяемкие операции сгруппировать в программируемые на языке ассемблера субмодули. Это допускают все пакеты современных языков программирования высокого уровня абстракции, а результатом всегда является существенное повышение быстродействия программ.

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

    2. О компиляторах


    Какой ассемблер лучше?


    Для процессора x86-x64, имеется более десятка различных ассемблер компиляторов. Они отличаются различными наборами функций и синтаксисом. Некоторые компиляторы больше подходят для начинающих, некоторые ― для опытных программистов. Некоторые компиляторы достаточно хорошо документированы, другие вообще не имеют документации. Для некоторых компиляторов разработано множеством примеров программирования. Для некоторых ассемблеров написаны учебные пособия и книги, в которых подробно рассматривается синтаксис, у других нет ничего. Какой ассемблер лучше?

    Учитывая множество диалектов ассемблеров для x86-x64 и ограниченное количество времени для их изучения, ограничимся кратким обзором следующих компиляторов: MASM, TASM, NASM, FASM, GoASM, Gas, RosAsm, HLA.

    Какую операционную систему вы бы хотели использовать?


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

    Windows DOS Linux BSD QNX MacOS, работающий на
    процессоре Intel/AMD
    FASM x x x x
    GAS x x x x x x
    GoAsm x
    HLA x x
    MASM x x
    NASM x x x x x x
    RosAsm x
    TASM x x

    Поддержка 16 бит


    Если ассемблер поддерживает DOS, то он поддерживает и 16-разрядные команды. Все ассемблеры предоставляют возможность писать код, который использует 16-разрядные операнды. 16-разрядная поддержка означает возможность создания кода, работающего в 16-разрядной сегментированной модели памяти (по сравнению с 32-разрядной моделью с плоской памятью, используемой большинством современных операционных систем).

    Поддержка 64 бит


    За исключением TASM, к которому фирма Borland охладела в середине нулевых, и, который не поддерживает в полном объеме даже 32-разрядные программы, все остальные диалекты поддерживают разработку 64-разрядных приложений.

    Переносимость программ


    Очевидно, что вы не собираетесь писать код на ассемблере x86-x64, который запускался бы на каком-то другом процессоре. Однако, даже на одном процессоре вы можете столкнуться с проблемами переносимости. Например, если вы предполагаете компилировать и использовать свои программы на ассемблере под разными операционными системами. NASM и FASM можно использовать в тех операционных системах, которые они поддерживают.

    Предполагаете ли вы писать приложение на ассемблере и затем портировать, это приложение с одной ОС на другую с «перекомпиляцией» исходного кода? Эту функцию поддерживает диалект HLA. Предполагаете ли вы иметь возможность создавать приложения Windows и Linux на ассемблере с минимальными усилиями для этого? Хотя, если вы работаете с одной операционной системой и абсолютно не планируете работать в какой-либо другой ОС, тогда эта проблема вас не касается.

    Поддержка высокоуровневых языковых конструкций


    Некоторые ассемблеры предоставляют расширенный синтаксис, который обеспечивает языковые высокоуровневые структуры управления (типа IF, WHILE, FOR и так далее). Такие конструкции могут облегчить обучение ассемблеру и помогают написать более читаемый код. В некоторые ассемблеры встроены «высокоуровневые конструкции» с ограниченными возможностями. Другие предоставляют высокоуровневые конструкции на уровне макросов.

    Никакой ассемблер не заставляет вас использовать какие-либо структуры управления или типы данных высокого уровня, если вы предпочитаете работать на уровне кодировки машинных команд. Высокоуровневые конструкции ― это расширение базового машинного языка, которое вы можете использовать, если найдете их удобными.

    Качество документации


    Удобство использования ассемблера напрямую связано с качеством его документации. Учитывая объем работы, который тратится для создания диалекта ассемблера, созданием документации для этого диалекта авторы компиляторов практически не заморачиваются. Авторы, расширяя свой язык, забывают документировать эти расширения.

    В следующей таблице описывается качество справочного руководства ассемблера, которое прилагается к продукту:

    Документация Комментарии
    FASM Хорошая Большую часть свободного времени автор отдает в разработку инновационного FASMG. Тем не менее, автор обеспечивает поддержку FASM время от времени обновляет мануалы, а новые функции описывает на собственном форуме. Документацию можно считать достаточно хорошей. Веб-страница документации.
    Gas
    Плохая
    документирован слабо и документация, скорее, имеет «общий вид». gas ― это ассемблер, который был разработан, чтобы можно было легко писать код для разных процессоров. Документация, которая существует, в основном описывает псевдо коды и ассемблерные директивы. В режиме работы «intel_syntax» документация практически отсутствует. Книги, в которых используется синтаксис «AT&T»: «Программирование с нуля» Джонатона Бартлетта и «Профессиональный язык ассемблера» Ричарда Блюма, Konstantin Boldyshev asmutils — Linux Assembly.
    GoAsm
    Слабая
    Большая часть синтаксиса описана в руководстве, и опытный пользователь найдет то, что ищет. Множество руководств и размещено на сайте (http://www.godevtool.com/). Несколько учебников GoAsm:

    HLA
    Обширая
    HLA имеет справочное руководство на 500 страниц. Сайт содержит десятки статей и документацию по HLA.
    MASM
    Хорошая
    Компанией Microsoft написано значительное количество документацию для MASM, существует большое количество справочников написанных для этого диалекта.
    NASM
    Хорошая
    Авторы NASM больше пишут программное обеспечение для этого диалекта, оставляя написание руководства на «потом». NASM существует достаточно долго, поэтому несколько авторов написали руководство для NASM Джефф Дунтеман (Jeff Duntemann) «Assembly Language Step-by-Step: Programming with Linux», Jonathan Leto «Writing A Useful Program With NASM», на русском языке есть книга Столярова (Сайт А.В. Столярова).
    RosAsm
    Слабая
    не очень интересные «онлайновые учебники».
    TASM
    Хорошая
    Компания Borland в свое время выпускала отличные справочные руководства, для TASM были написаны справочные руководства авторами-энтузиастами не связанными с фирмой Borland. Но Borland больше не поддерживает TASM, поэтому большая часть документации, предназначенная для TASM, не печатается и ее становится всё труднее и труднее найти.


    Учебники и учебные материалы


    Документация на самом ассемблере, конечно, очень важна. Еще больший интерес для новичков и других, изучающих язык ассемблера (или дополнительные возможности данного ассемблера), ― это наличие документации за пределами справочного руководства для языка. Большинство людей хотят, чтобы учебник, объясняющий, как программировать на ассемблере, не просто предоставляет синтаксис машинных инструкций и ожидает, что читателю объяснят, как объединять эти инструкции для решения реальных проблем.

    MASM является лидером среди огромного объема книг, описывающих, как программировать на этом диалекте. Есть десятки книг, которые используют MASM в качестве своего ассемблера для обучения ассемблеру.

    Большинство учебников по ассемблеру MASM/TASM продолжают обучать программированию под MS-DOS. Хотя постепенно появляются учебники, которые обучают программированию в Windows и Linux.

    Комментарии
    FASM Несколько учебников, в которых описывается программирование на FASM:

    Gas
    Учебник с использованием синтаксиса AT&T
    Учебник Ассемблер в Linux для программистов C
    HLA
    32-разрядная версия «The Art of Assembly Language Programming» (существует и в электронной, и в печатной форме), программирование под Windows или Linux
    MASM
    большое количество книг по обучению программированию под DOS. Не очень много книг о программировании под Win32/64 Пирогов, Юров, Зубков, Фленов
    NASM
    много книг, посвященных программированию в DOS, Linux, Windows. В книге Джеффа Дунтемана «Assembly Language Step-by-Step: Programming with Linux» используется NASM для Linux и DOS. Учебник Пола Картера использует NASM (DOS, Linux).
    TASM
    Как и для MASM, для TASM было написано большое количество книг на основе DOS. Но, так как Borland больше не поддерживает этот продукт, писать книги об использовании TASM перестали. Том Сван написал учебник, посвященный TASM, в котором было несколько глав о программировании под Windows.


    3. Литература и веб ресурсы


    Beginners


    1. Абель П. Язык Ассемблера для IBM PC и программирования. – М.: Высшая школа, 1992. – 447 с.
    2. Брэдли Д. Программирование на языке ассемблера для персональной ЭВМ фирмы IBM.– М.: Радио и связь, 1988. – 448 с.
    3. Галисеев Г.В. Ассемблер IBM PC. Самоучитель.: – М.: Издательский дом «Вильямс», 2004. – 304 с.: ил.
    4. Дао Л. Программирование микропроцессора 8088. – М.: Мир, 1988. – 357 с.
    5. Жуков А.В., Авдюхин А.А. Ассемблер. – Спб.: БХВ-Петербург, 2003. – 448 с.: ил.
    6. Зубков С.В., Ассемблер для DOS, Windows и UNIX. – М.: ДМК Пресс, 2000. – 608 с.: ил. (Серия «Для программистов»).
    7. Ирвин К. Язык ассемблера для процессоров Intel, 4-е издание.: пер. с англ. – М.: Издательский дом «Вильямс», 2005. – 912 с.: ил. – Парал. тит. англ.(см. также свежее 7-ое издание в оригинале)
    8. Нортон П., Соухэ Д. Язык ассемблера для IBM PC.– М.: Компьютер, 1992.– 352 с.
    9. Пильщиков В.Н. Программирование на языке ассемблера IBM PC.– М.: ДИАЛОГ-МИФИ, 1994–2014 288 с.
    10. Скляров И.С. Изучаем ассемблер за 7 дней www.sklyaroff.ru


    Advanced


    1. Касперски К. Фундаментальные основы хакерства. Искусство дизассемблирования. – М.: СОЛОН-Пресс, 2004. 448 с. – (Серия «Кодокопатель»)
    2. Касперски К. Техника отладки программ без исходных текстов. – Спб.: БХВ-Петербург, 2005. – 832 с.: ил.
    3. Касперски К. Компьютерные вирусы изнутри и снаружи. – Спб.: Питер, 2006. – 527 с.: ил.
    4. Касперски К. Записки исследователя компьютерных вирусов. – Спб.: Питер, 2006. – 316 с.: ил.
    5. Кнут Д. Искусство программирования, том 3. Сортировка и поиск, 2-е изд.: пер. с англ. – М.: Издательский дом «Вильямс», 2003. – 832 с.: ил. – Парал. тит. англ.
    6. Колисниченко Д.Н. Rootkits под Windows. Теория и практика программирования «шапок-невидимок», позволяющих скрывать от системы данные, процессы, сетевые соединения. – Спб.: Наука и Техника, 2006. – 320 с.: ил.
    7. Лямин Л.В. Макроассемблер MASM.– М.: Радио и связь, 1994.– 320 с.: ил.
    8. Магда Ю. Ассемблер для процессоров Intel Pentium. – Спб.: Питер, 2006. – 410 с.: ил.
    9. Майко Г.В. Ассемблер для IBM PC.– М.: Бизнес-Информ, Сирин, 1997.– 212 с.
    10. Уоррен Г. Алгоритмические трюки для программистов, 2-е изд.: пер. с англ. – М.: Издательский дом «Вильямс», 2004. – 512 с.: ил. – Парал. тит. англ.
    11. Скляров И.С. Искуство защиты и взлома информации. – Спб.: БХВ-Петербург, 2004. – 288 с.: ил.
    12. Уэзерелл Ч. Этюды для программистов: Пер. с англ. – М.: Мир, 1982. – 288 с., ил.
    13. Электронная библиотека братьев Фроловых www.frolov-lib.ru
    14. Чекатов А.А. Использование Turbo Assembler при разработке программ.– Киев: Диалектика, 1995.– 288 с.
    15. Юров В. Assembler: специальный справочник.– Спб.: Питер, 2001.– 496 с.: ил.
    16. Юров В. Assembler. Практикум. 2-е изд. – Спб.: Питер, 2006. – 399 с.: ил.
    17. Юров В. Assembler. Учебник для вузов. 2-е изд. – Спб.: Питер, 2007. – 637 с.: ил.
    18. Пирогов В. Assembler учебный курс. 2001 Нолидж
    19. Пирогов В. АССЕМБЛЕР учебный курс 2003 Нолидж-БХВ
    20. Пирогов В. Assembler для windows 
      1-ое издание ― М.: изд-во Молгачева С.В., 2002 
      2-ое издание ― СПб.:. БХВ-Петербург, 2003 ― 684 с.: ил. 
      3-ье издание ― СПб.:. БХВ-Петербург, 2005 ― 864 с.: ил. 
      4-ое издание ― СПб.:. БХВ-Петербург, 2012 ― 896 с.: ил.
    21. Пирогов В. Ассемблер на примерах. ― СПб.:. БХВ-Петербург, 2012 ― 416 с.: ил.
    22. Пирогов В. АССЕМБЛЕР и дизассемблирование. ― СПб.:. БХВ-Петербург, 2006. ― 464 с.: ил.
    23. Пирогов В. работа над книгой '64-битовое программирование на ассемблере (Windows,Unix)'. В книге рассматривается программирование на fasm в 64-разрядных Windows и Unix
    24. Юров В., Хорошенко С. Assembler: учебный курс.– Спб.: Питер, 1999. – 672 с.
    25. Ю-Чжен Лю, Гибсон Г. Микропроцессоры семейства 8086/8088. Архитектура, программирование и проектирование микрокомпьютерных систем.– М.: Радио и связь, 1987.– 512 с.
    26. Agner Fog: Software optimization resources (assembly/c++) 1996 – 2017. Веб-страница
    27. Intel ® 64 and IA-32 Architectures Optimization Reference Manual
    28. Intel ® 64 and IA-32 Architectures Software Developer’s Manual Volume 1: Basic Architecture
    29. Intel ® 64 and IA-32 Architectures Software Developer’s Manual Volume 2A: Instruction Set Reference, A-M
    30. Intel ® 64 and IA-32 Architectures Software Developer’s Manual Volume 2B: Instruction Set Reference, N-Z
    31. Intel ® 64 and IA-32 Architectures Software Developer’s Manual Volume 3A: System Programming Guide, Part 1
    32. Intel ® 64 and IA-32 Architectures Software Developer’s Manual Volume 3B: System Programming Guide, Part 2
    33. Leiterman J.C. 32/64-BIT 80x86 Assembly Language Architecture. © 2005, Wordware Publishing, Inc (568 pages) 2320 Los Rios Boulevard Plano, Texas 75074
    34. Turbo Assembler® Version 3.2 User's Guide Borland International. Inc 1800 Green Hills Road P.O. BOX 660001, Scotts Valley, CA 95067-0001
    35. Статьи с сайта wasm.in
    36. Статьи с сайта sasm.narod.ru
    37. Сайт MASM32 и форум
    38. Сайт FASM и форум
    39. Сайт NASM

    4. Практика


    Итак, вы уже знаете, что такое ассемблер и с чем его едят. Вы запаслись парой/тройкой книг и веб мануалами, возможно определились и с компилятором… К сожалению уроки программирования выходят за рамки данной статьи, но для тех чей выбор пал на MASM/FASM можете воспользоваться следующими макетами:


    Остается открытым вопрос, в каком редакторе писать код? Кто-то пишет в блокноте и компилирует через командную строку, более смекалистые готовят скрипты – упрощая процесс, другие же используют специальные среды разработки. Да, есть IDE и в области низкоуровневого программирования, их обзор также выходит за рамки статьи. Однако пользуясь возможностью, осмелюсь предложить вам попробовать свою среду для программирования на ассемблере – ASM Visual. Кроме базовых возможностей, отличается от аналогов наличием инструментов рефакторинга, метрик кода, в целом более интуитивно понятными интерфейсами и собственным типом проекта.

    спойлер
    Так получилось, что среда не полностью бесплатная. Вы можете поддержать проект приобретая Pro лицензию за свободную стоимость. Используйте код: HABR_zzdBG1qadG (если бесплатно установите бегунок в позицию 0).

    Желаем вам, друзья, значительных достижений и новых знаний в 2018 году!

    С уважением
    Михаил Смоленцев MiklIrk (Иркутский государственный университет путей сообщения),
    Алексей Гриценко expressrus (Донской государственный технический университет).


    Ps1: Уважаемый, Хабрахабр! Добавьте в ваш редактор подсветку ассемблера (Intel-синтаксис), это пригодится для будущих статей!

    Ps2: В скором времени мы запустим портал с тестами (вопрос – варианты ответа) на знание ассемблера и архитектуры компьютера. Тесты будут структурированы по уровню сложности. Если вы преподаете ассемблер или имеете достаточные знания в этой области – напишите нам на почту express-rus@yandex.ru вы можете принять участие предложив свой тест в систему.
    Поделиться публикацией
    Похожие публикации
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 166
    • 0

      А ещё в природе есть такая вещь, как i386 в корпусе PQFP. У нас под него писали на ассемблере, потому что nasm может сразу выдать Intel hex, содержащий только нашу программу, а возиться для получения аналогичного результата на C никому не хотелось.

      • НЛО прилетело и опубликовало эту надпись здесь
        • –1

          На работе у меня Windows (7, WSL нету), там не ELF’ы и objcopy есть разве что в cygwin (у меня тоже установлен). И вряд ли всё так просто: нужно разместить безусловный переход по строго определённому адресу (вектора прерываний), а сама программа должна быть по нулевому адресу. И ещё к аргументам нужно добавить, как минимум, -march=i386 -static -Os. И нужно понять как записывать и считывать регистры специального назначения. Разобраться можно, но зачем?


          Помимо этого написание программы на ассемблере позволило использовать «память» в режиме «только чтение», обошедшись без стека и без собственно реализации записи в память — самой памяти в системе никогда не было, была имитация на FPGA, которую тоже нужно написать.

          • 0
            Fasm тоже прекрасно выдает чистый бинарник.
            • –1

              Не понимаю, к чему этот комментарий. Если какой‐то *asm не способен выдавать «чистый бинарник», то зачем он вообще нужен?

              • –2
                К тому что из ряда ассемблеров вы не можете получить ничего, кроме, скажем, .exe без дополнительных утилит.
                • +2

                  скорее всего и не .exe а .obj

                  • 0
                    Да, но это уже деталь. На Fasm много проще создать код «вне формата».
                    • 0
                      На Fasm много проще создать код «вне формата».

                      Конечно, на то он и FASM. ;)

      • 0
        Говоря про Ирвина, я бы «обновил» издание до 7-го, пусть оно и на английском языке
        • 0
          Добавил в скобки факт его существования. Благодарю.
        • +3
          Хех… Я был уверен, что НИКОГДА уже не увижу на Хабре (да и любом другом сайте) статьи про ассемблер.
          Вспомнил молодость, ассемблер, Clipper, с чего начинается Родина… В смысле, первые символы dos-овского .exe-файла и первые символы .exe-файла под Windows, как ставили Windows 95 поверх MS-DOS и Windows 3.1, а потом пытались откатиться при помощи установки Windows 3.1… Эх…
          • НЛО прилетело и опубликовало эту надпись здесь
            • +6
              Одно дело ассемблер для этих микроконтроллеров, другое дело x64
              • +4
                Под такие микроконтроллеры можно тоже писать на плюсах, есть положительный опыт с attiny. Не микроволновкой, правда, а лазером в экспериментальной установке управляли, но то такое.
                • НЛО прилетело и опубликовало эту надпись здесь
                  • +2
                    Аналогично. Управляем установкой, МК — Atmega какая-то, пишем на С. Наверное можно и на асме, но зачем? На ассемблере написал «Жизнь» — когда на курсах по нему учился и всё.
                  • +2
                    В мире, где железо стремительно дешевеет, а программиста — стремительно дорожают ваше утверждение выглядит сомнительным.
                    • +1
                      Дешевеет уже давно не так стремительно как раньше, и со временем будет дешеветь всё меньше.

                      Впрочем соглашусь, что за исключением очень редких случаев, писать прямо на асме нет смысла.
                      • 0
                        Ну да, поскольку мы, кажется, уже упёрлись в стоимость пластика и рамки с выводами.
                      • НЛО прилетело и опубликовало эту надпись здесь
                    • +3

                      Я на ассемблере не пишу, пишу на C++, но знать и понимать его стоит. Как минимум для целей отладки или понимания происходящего под капотом: иногда после этого сильно по другому смотришь на более высокий уровень. Обязательно нужно знакомится с соглашениями по вызовам для вашей платформы и так далее. Особенно это актуально для всякого embedded.

                    • +5
                      Может быть у вас есть пример из реального проекта, когда вставки на ассемблере существенно дали выигрыш в скорости для десктоп приложения? Или использование ассемблера все таки ограничивается драйверами и узкоспециализированным ПО, где действительно нужно быть уверенным в том, что происходит на уровне процессора? Я не пытаюсь приуменьшить достоинства ассемблера, просто мне кажется, что современные компиляторы оптимизируют код лучше, чем среднестатистический программист сможет написать ассемблере.

                      Знание ассемблера безусловно полезное, например в случае отладки, когда есть только бинарный код, но насколько целесообразно в прикладном ПО делать вставки на ассемблере?
                      • –1
                        Ну, здесь на Хабре была серия статей — человек написал на языке ассемблера сервер и форум на его основе, поищите.
                        • +5

                          Да, и выяснилось, что он не самый быстрый. Например, фаза рендеринга markdown в html там не кешируется.

                          • 0
                            Ну, я просто вспомнил пример достаточно большого проекта. Да и кеширование/его отсутствие — это не к языку претензия.
                            • 0
                              А к чему? Если написание остального съело время, которое требовалось для осмысления необходимости кэша и его реализации.
                              • 0
                                Оно могло изначально не предполагаться по каким-то причинам. Или необходимость его не была осмыслена в силу неопытности автора, при том что времени у него был вагон.
                                • 0
                                  Ну так это хороший пример premature optimization. Оптимизации не того, не там и не тогда, когда нужно.
                            • +1

                              Кстати, кешируется:


                              create table Posts (
                                id          integer primary key autoincrement,
                                threadID    integer references Threads(id) on delete cascade,
                                userID      integer references Users(id) on delete cascade,
                              
                                postTime    integer, 
                                ReadCount   integer,
                                Content     text,
                                Rendered    text  -- здесь
                              );
                            • +1
                              Если говорить про ассемблерные вставки, а не про написание программы полностью на ассемблере, то они в высокопроизводительных программах используются повсеместно: в рендерерах 3D, в видеокодеках, в программах для изменения размеров изображений.

                              Есть еще противоположная сторона оптимизации: когда нужно уместить код в минимальное количество байт, тогда приходится использовать ассемблер и всякие трюки. Например, декомпрессор в паковщике исполняемых файлов upx написан на ассемблере.
                              • +2
                                В первом случае почти всегда достаточно интринсиков.
                              • 0

                                https://github.com/cisco/openh264 — полистайте здесь

                                • 0
                                  Если прям реальный бытовой проект из моего опыта, в системе документооборота были переписаны на асм функции подсчета контрольных сумм файлов и хеширования паролей, что в обоих случаях достаточно заметно снизило время ожидания клиента.
                                  • +7

                                    Ну, не буду сильно спорить..


                                    Возьмем достаточно большой файл.


                                    time cat 700mb.iso > /dev/null 
                                    
                                    real    0m13.280s
                                    user    0m0.024s
                                    sys 0m0.632s
                                    
                                    time cat 700mb.iso > /dev/null 
                                    
                                    real    0m0.275s
                                    user    0m0.004s
                                    sys 0m0.220s

                                    Из диска он читается 13с, из кеша — меньше секунды.


                                    time cat 700mb.iso | md5sum -
                                    73fe07300ad456cff2f7b9524c295fd1  -
                                    
                                    real    0m1.518s
                                    user    0m1.336s
                                    sys 0m0.544s

                                    Хеш-сумма этих 700 мб считается около 1 с.


                                    Нехитрый эксперимент показывает, что самое медленное при работе с файлами — дисковый ввод-вывод; его в первую очередь нужно оптимизировать.

                                    • +1
                                      Возможно, в высокоуровневом варианте был какой-то алгоритмический просчет, вроде лишних выделений памяти, чтения из файла по байту и т.д?

                                      Вот сгенерированный С++ компилятором код умножения на 5 и суммирования 1024 байт из буффера, и я с трудом представляю, каких сил будет стоить написание и сопровождение подобного кода вручную:

                                      godbolt.org/g/2QW1Qx
                                      • 0

                                        Так на ассемблере писать никто не будет. С этим замечательно справится компилятор.
                                        Цикл из 1024 сложений и одно умножение на 5 (2 сдвига и сложение) — это как-то более логично.

                                        • +1
                                          А что ж тогда писать на ассемблере в контексте оптимизации?
                                          • +2

                                            А это смотря что нужно оптимизировать. В смысле написания и поддержки — 2 строки на C++ конечно же, оптимальное решение.
                                            В смысле быстродействия… Напрашивающийся цикл из 1024 сложений выглядит лучше… На 8086 это бы прокатило ;) Но компилятор лучше знает архитектуру процессора, и, подозреваю, что эти странные 128-битные операции неспроста..

                                            • 0
                                              Напрашивающийся цикл из 1024 сложений выглядит лучше…
                                              Вряд ли он лучше. Работать будет в лучшем случае так же, но скорее всего — медленнее. И дело не только в странных и не очень операциях, а еще и в ветвлениях и затратах на сам цикл.
                                              • +2

                                                Да. Если написать коротко и понятно — это будет, скорее всего, неоптимально. А если написать оптимально — будет сложно (а то и невозможно) поддерживать.
                                                Так, в вашем примере, если заменить int на short (или long) — компилятор использует совершенно другие инструкции. Получается, для разных типов данных написанный на ассемблере алгоритм нужно переписывать.

                                              • 0
                                                Нет, даже во времена 8086 для быстродействия приходилось разворачивать циклы, иначе ветвления пожирали всё время выполнения.
                                        • +1
                                          Вдогонку к предыдущему сообщению:

                                          … а С++ реализация cosine similarity между одним float-вектором размерностью 192 и 1.7 гигабайтами других таких же векторов с использованием SIMD-intrinsics вычисляется за 0.3 секунды на процессоре Celeron J1900 @ 1.99GHz, на NAS-е, внутри виртуалки.

                                          Не то, чтобы сильно быстро, но это даже не ноутбучный процессор, не самая быстрая память, еще и виртуалка.
                                        • +1
                                          Обработка изображения в моем/нашем FastRawViewer — это SSSE3 (и AVX2 на тех процессорах, где оно есть).
                                          Это не ассемблер в чистом виде, а вот как-то вот так:

                                          xlo = _mm256_unpacklo_epi16(row0, zero);
                                          xhi = _mm256_unpackhi_epi16(row0, zero);
                                          pix0_0_7 = _mm256_cvtepi32_ps(xlo);
                                          pix0_8_f = _mm256_cvtepi32_ps(xhi);
                                          row1 = _mm256_permutevar8x32_epi32(_mm256_loadu_si256((const _m256i*)&srcrow2[scol]), b256m);

                                          Относительно очень близкой по логике обработки dcraw/LibRaw, выигрыш на SSSE3 — примерно порядок, от AVX2 — еще раза в полтора (плюс dcraw/LibRaw — целочисленные, а FRV — внутри в плавучке, что несколько улучшает качество теней)

                                          • +1
                                            Это не просто «не ассемблер в чистом виде», это Си :)
                                            • 0

                                              Это даже не сколько Си, это интринсики :)

                                              • +6
                                                Так в том-то и посыл, что по-моему, чаще всего ассемблер для задач оптимизиции нужен только для того, чтобы читать код. А писать и проще и лучше на С/С++, используя интринсики там, где это нужно. Главное отличие в том, что программисту не нужно следить за регистрами и адресами.

                                                Возможно, бывают какие-то хитрые алгоритмы, которые очень сложно выразить в C и проще — на языке ассемблера, но я пока не смог представить ничего подобного.

                                                Конечно, бывают задачи, которые проще решаются на ассемблере: первое, что приходит в голову из того, что писал сам — загрузчик в MBR. Но когда речь идет об оптимизации, я подозреваю баг компилятора или ошибку в высокоуровневом коде.
                                                • 0
                                                  Так в том-то и посыл...

                                                  Полностью согласен.


                                                  что приходит в голову из того, что писал сам — загрузчик в MBR

                                                  Что удивительно, беглый поиск не показал мне ни одного pureC бутлодера в MBR на Си… Хотя вру: https://www.codeproject.com/Articles/664165/Writing-a-boot-loader-in-Assembly-and-C-Part хотя и тут без вставок никак.

                                                  • +1
                                                    Более новые архитектуры, чем x86, изначально разрабатываются с учётом того, чтобы загрузчик можно было писать на чистом Си с интринсиками.

                                                    Говорить «для загрузчика необходим ассемблер», глядя на x86 — всё равно, что говорить «для завода двигателя необходим кривой стартёр», глядя на 2101.
                                                    • 0

                                                      Тут конкретно про MBR речь была. Так то да, взять тот же UEFI.

                                                  • +1

                                                    Кстати, вспомнилось: мне однажды нужно было сделать инъекцию: был закрытый код, который вызывался в контексте ISR и ошибочно вызывал функцию логирования (косвенно, через общий код), которая аллоцировала большой буффер на стеке, чем срывала его, будучи запущенной из ISR.


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


                                                    Ну и да, я понимаю, что это костыль. Но решилось автоматом ещё несколько проблем и стало обоснованием более предметно предъявить разработчикам закрытой части SDK.

                                                • +1
                                                  Ну да. Адресную арифметику оставляю компилятору.
                                                  Плюс, некоторые компиляторы позволяют себе переупорядочить порядок действий.

                                                  Но смысл то один — пишу ровно ассемблерные куски правда на немного птичьем языке
                                              • 0
                                                MacIn, acyp спасибо за указания на статьи. Но я имел ввиду пример, когда целесообразно сделать ассемблерные вставки. Вот пишу я некоторое десктопное приложение на C++ и в какой-то момент понимаю, что вот здесь лучше написать на ассемблере. Есть ли такое в современное практике у кого-нибудь? И если да, то какой прирост получился? Понятно, что если захотеть, то можно написать сколь угодно большое приложение на ассемблере, включая многопоточность, работу с сетью и т.д. и т.п. Но хочется не доказательства того что это возможно, а примера когда это было целесообразно. Не холивара ради, а просто из любопытства. Так как я вряд ли смогу написать на ассемблере эффективнее компилятора, но вполне допускаю, что такие люди есть и такие ситуации тоже.
                                                • +3
                                                  У меня есть вполне обширный опыт по написанию asm-функций для вычислительно-интенсивных частей алгоритмов, с применением simd-ов. Прирост для конкретно этого кода в разы, иногда в десятки раз. Для всего приложения включение оптимизаций даёт прирост в несколько раз. Правда этих оптимизаций в приложении уже довольно много накопилось.
                                                  Но это именно отдельные функции, а не вставки asm-а в С-код.
                                                  • 0
                                                    Спасибо. Тут еще выше привели пример с инструкциями SSE3, не совсем про ассемблер, но то же интересно.
                                                    • +2
                                                      Интринсики (intrinsics) — неплохая штука, когда нужно быстро объяснить глупому компилятору, как можно сделать при помощи simd-ов что-то относительно простое. Но к сожалению они не дают контроля над регистрами. Даже в том примере, на который вы обратили внимание, нет никаких гарантий, что, например, переменная «xlo» не будет запихнута в стек в промежутке между первой и третьей строчками кода (а это, на минуточку, 32 байта). И такие ситуации частенько возникают, когда количество одновременно используемых simd-регистров (переменных) становится больше 6-8 (при том, что всего их доступно 16 в режиме х86-64).
                                                      С другой стороны хорошие компиляторы могут и самостоятельно использовать эффективные simd-инструкции при правильно написанном С-коде и высоком уровне оптимизации. И временами это бывает не менее эффективно, чем использование интринсиков.
                                                      • 0
                                                        С intrinsics ещё такая штука, если поддержку того или иного instruction set надо проверять в runtime, приходится generic/optimized версии функций компилировать отдельно. Или же можно использовать явный вызов через asm. Кстати, о SSE… Не зря например в протоколе Kafka используют CRC32C. Потому что для него есть инструкции в SSE4.2.
                                                        • +2
                                                          приходится generic/optimized версии функций компилировать отдельно

                                                          Зачем? Есть же атрибуты, вроде __attribute__((target("ssse3"))) для gcc и clang. Можно в одном translation unit держать версии для нескольких SIMD-наборов.

                                                          gcc вам даже сам трамплин сгенерирует.
                                                          • 0
                                                            Да, по описанию всё так, только не работало. Оказывается починили в gcc 4.9:
                                                            It is now possible to call x86 intrinsics from select functions in a file that are tagged with the corresponding target attribute without having to compile the entire file with the -mxxx option. This improves the usability of x86 intrinsics and is particularly useful when doing Function Multiversioning.
                                                            • 0
                                                              Если вдруг действительно будете этим пользоваться, то имейте в виду, что clang никаких трамплинов не генерирует. По крайней мере, не генерировал примерно год назад.
                                                  • +1
                                                    Использование знания ассемблера в C/C++ разработке не ограничивается только переписыванием кусков кода на ассемблере. У меня лично самый частый сценарий использования ассемблера — это смотреть, в какой вообще ассемблерный код компилятор превратил критичный кусок C++ кода. Например заинлайнил ли вызов функции, или статическую константу. Если обнаружен неоптимальный вызов — значит можно пытаться выиграть ещё, причём косвенно (меняя высокоуровневый код), кстати то ещё развлечение по сравнению с переписыванием напрямую на асме.
                                                    • +1
                                                      Лет ~20 назад в бытность школьником писал свою реализацию графических примитивов для VESA-режимов (с высоким разрешением) на Borland Pascal (я тогда не знал что есть родные BGI драйверы для этих режимов). Вывод работал заметно медленно, особенно линии и окружности. После переписывания этих методов (и еще нескольких оптимизаций) на inline-ассемблер скорость возросла на порядок минимум. Но сейчас компиляторы гораздо умнее.
                                                    • +1
                                                      В драйверах к серьезным ОС, к счастью, почти не встречается ассемблер — все абстрагируется самой ОС и HALами. Там и так все на шаманстве зачастую, из-за специфики работы с железом, а если еще и писать опкодами, то это шаманство еще и станет нечитабельно.
                                                      • 0
                                                        Может быть у вас есть пример из реального проекта, когда вставки на ассемблере существенно дали выигрыш в скорости для десктоп приложения?


                                                        1. Битовый массив. Ассемблерные инструкции позволили напрямую ставить/снимать/проверять бит. То же самое чрез маску — работало прилично медленней.
                                                        2. Критическая секция для однопроцессорных машин. Работала без переключения в режим ядра для случая, когда вход в критсекцию свободен. Применялась в серверном приложении при одновременной работе 20 тредов. Проблема была в том, что нужно было обращение к регистру FS, которое компилятор не поддерживал

                                                        но насколько целесообразно в прикладном ПО делать вставки на ассемблере?
                                                        В прикладном не знаю, а в библиотеках такого очень много. Можете полюбоваться на ассемблерную версию memchr из glibc.
                                                        • +1
                                                          Битовый массив. Ассемблерные инструкции позволили напрямую ставить/снимать/проверять бит. То же самое чрез маску — работало прилично медленней.
                                                          Хм, мне казалось, что компиляторы умеют генерировать битовые инструкции из обращений к битовым полям.
                                                          • +1
                                                            Конечно умеют: godbolt.org/g/oDZDxw
                                                            • 0

                                                              На моем опыте под битовыми операциями понимаются следующие конструкции: https://godbolt.org/g/1Ayj7e
                                                              В то время как это вполне себе описывается:
                                                              mov eax, dword ptr [x]
                                                              sub eax, 5
                                                              BTR argc, eax
                                                              add eax, 7
                                                              BTS argc, eax

                                                          • +1
                                                            Конкретно Delphi 5 — не умел. Компиляторы вообще не умеют использовать наборы инструкций, получившие распространение после их написания. :-)
                                                            • +3
                                                              Напомню, что здесь обсуждают "как зачем писать на ассемблере в 2018 году", а не «зачем надо было писать на ассемблере в 1999 году, когда компиляторы были глупее, а системы команд — проще».
                                                              • 0
                                                                А чем 2018ый год отличается? Вы или ждете, пока выйдет релиз компилятора с поддержкой нужных вам команд — или пишете ассемблерные вставки. Если не боитесь, то на опенсорсных компиляторах можно ещё и нестабильные ночные билды попробовать.

                                                                Лично мне больше нравится стабильный проверенный компилятор + ассемблерные вставки, чем экспериментальные версии.
                                                        • 0

                                                          Есть пример проекта, когда использование ассемблера дало прирост в энергоэффективности устройств.
                                                          В студенческие годы разрабатывал с товарищем АСКУЭ (автоматическая система контроля и учёта электроэнергии). Использование ассемблера и знание режимов работы микроконтроллера позволило запитать 7 кучек (по кучке на подъезд) из 30+ устройств (по устройству на квартиру) очень небольшим блоком питания. Не помню точно потребления, но та что-то в районе микроампер в режиме ожидания и раз в 15 минут при опросе — милиамперы для каждого устройства) Что дало преимущество, когда понадобилось поставить ИБП для всех устройств.

                                                          • 0
                                                            Есть такие примеры (это десктопные игры): ассемблерные реализации работы с растром и геометрией (особенно на базе MMX/SSE) зачастую дают существенный выигрыш в скорости. Беда правда в том, что такой код привязан к платформе, и не работает на ARM :(
                                                          • +1
                                                            Документация FASM слабая? Простите, но базовая документация, которая идет в стандартной поставке — исчерпывающая.
                                                            • 0

                                                              Я не знаю откуда это пошло, что у FASM документация слабая???


                                                              Это не так! FASM ассемблер простой и та документация которая идет в стандартной поставке и вправду исчерпывающая.

                                                              • +1
                                                                У нас с коллегой немного противоречивое мнение. Когда он появиться (а время у него GMT+8) мы придем к общей позиции и обязательно ответим вам, так же в случае чего подредактируем этот момент в статье. Благодарю.
                                                                • +1
                                                                  Возможно это и известно вам, но все же, уж коли зашла речь: в избранное можно заносить не только статьи, но и комменты. Сверхполезная вешь, ибо в комментах часто бывает много полезной информации помимо статей. Ну и плюс можно вернуться к обсуждению позднее.
                                                                  • 0
                                                                    Нет не замечал, спасибо что сказали. FASM кстати поправили.
                                                                    • 0
                                                                      Вот-вот) Иконка закладки, аналогичная иконке закладки у статей. Просто подумал, что ситуациях подобного рода будет очень удобно добавлять комменты в избранное, дабы в дальнейшем обсудить их с коллегами.

                                                                      За FASM спасибо, у них ман действительно неплохой.
                                                                • +1
                                                                  Обсудили и поправили. Спасибо.
                                                                • +7
                                                                  Статья посвящена языку ассемблер с учетом актуальных реалий.

                                                                  К сожалению про язык ассемблера в статье ничего. Да и озаглавить бы её стоило, наверное, «Сравнение ассемблеров», чтобы не вводить людей в заблуждение. По моему мнению, (не могу судить о большинстве) заголовок «Как писать на ассемблере в 2018 году» предполагает, что в статье пойдёт речь о там как писать код на языке ассемблера с учётом современных наборов команд или технологий.


                                                                  А кто-то реально сейчас пишет на TASM да ещё и для DOS? Устаревшие вузовские курсы не в счёт.

                                                                  • 0
                                                                    Вводная статья, думаю многим хотелось бы больше практики, в следующий раз мы сосредоточимся именно на высказанных вами вопросах. На тасме только поддерживают старые проекты.
                                                                  • +1

                                                                    Помню в своём время игрался с FASM и MASM. В качестве IDE использовал RadASM. Давно это было. Последний раз когда имел дело с ASM — использвоал GNU Assembler. В наше время материалов по Asm-тематике мало, народ всё больше к высокоуровневым ЯП тяготеет. Спасибо автору, что занимается просветительской деятельностью по данной тематике в 2018, может кого-то цикл статей по теме заинтересует, и появится новое поколение любителей ассемблера:)

                                                                    • +1
                                                                      Реквестирую разработку на асм под х64.
                                                                      • +5
                                                                        Спасибо, что хоть кто-то ещё пишет про ассемблер. Очень мало про ассемблер статей
                                                                        • +2
                                                                          FASM для BSD существует.
                                                                          На flatassembler.net/download.php 4-я ссылка, в описании упоминается OpenBSD
                                                                          • 0
                                                                            Есть такое дело. Добавили. Благодарю.
                                                                            • 0

                                                                              Кстати, для MacOS X тоже:


                                                                              https://board.flatassembler.net/topic.php?t=13413


                                                                              И конечно для Menuet/KolibriOS и всяких экспериментальных ОС. Вообще, FASM, несмотря на то, что написан на ассемблере, переносится очень легко на всяких ОС. Намного легче чем тот же NASM.

                                                                          • +11
                                                                            Не знаю, как других, а меня уже давненько выбешивают такие статьи… «Как писать на ассемблере в 2018»…
                                                                            Очевидно, что имеется ввиду The Assembler x86. Не какой-то там ARM9 с его баррел-шифтами (правда, кому они нужны?), не какая-то там SH, и не о разнице между MIPS и Loongson, не об Эльбрусовском чего-то там они придумали, не о сетевых всяких там — об их величестве x86.
                                                                            Ну, ладно, допустим… Об x86-64… Допустим… Так опять-же не об жонглированием ядрами и атомных инструкциях…
                                                                            «Я писал на АСМЕ» — ага, да… Вотиманно на «АСМЕ».
                                                                            • +2
                                                                              правда, кому они нужны?


                                                                              Гггг. Сегодня сравнивал производительность на Cortex-M3 двух реализаций AES-128 — на C и на асме, в последней как раз barrel shift используется.

                                                                              Ну, асм быстрее. Меньше, чем в два раза, но быстрее. Ещё б на фоне недостатков кода на нём это кого-нибудь бы в контексте данного проекта волновало бы.
                                                                              • +2
                                                                                На мой взгляд, это был сарказм, учитывая общую тональность коммента.
                                                                              • 0
                                                                                В целом всё правильно, но можно же было всё тоже самое и без приношения жертв богу сарказма. Не все верят в то что на технической площадке обязательно надо блистать остроумием.
                                                                              • +1
                                                                                На сайте А.В. Столярова книга по NASM, а у вас в таблице она отнесена к GAS. И если не ошибаюсь, то синтаксис AT&T там только упоминается дальше 5й страницы идет интеловский синтаксис.
                                                                                • 0
                                                                                  Спасибо что заметили. Исправили.
                                                                                • +6
                                                                                  Использование ассемблера в вычислительном коде скорее всего приведет к замедлению ваших программ.
                                                                                  «Компактный код» сейчас совершенно не значит «быстрый код».
                                                                                  Писать UI, или IO на ассемблере это практически убивать свое время на скучнейшую работу. Если так уж горит — можно сделать всю обвязку на плюсах или еще чем то, а потом сделать ассемблерную вставку.
                                                                                  • +2
                                                                                    «Использование ассемблера в вычислительном коде скорее всего приведет к замедлению ваших программ.»

                                                                                    Моих — да, любых — нет)
                                                                                    К слову, разработчики видеокодеков по-прежнему активно используют асм. Посмотрите исходные коды libvpx, libx265, libx265, да вообще ffmpeg директории asm.
                                                                                    • 0
                                                                                      Популярные видеокодеки работают на миллиардах устройств, плюс особенности задачи делают выгодным вложение десятков тысяч человекочасов на разработку. В большинстве же остальных случаев это просто невыгодно, увы.
                                                                                    • –3
                                                                                      Использование ассемблера в вычислительном коде скорее всего приведет к замедлению ваших программ.

                                                                                      А вы пробовали? Я да. Несколько раз. И дело в том, что нет, не получается. На ассемблере всегда получается намного быстрее.


                                                                                      На C/C++ можно написать быстрые программы, но дело в том, что надо ясно представлять как они должны выглядеть на ассемблере. А потом обмануть компилятора, чтобы сгенерировать нужный ассемблерский код. Для меня проще написать сразу на ассемблере. :P

                                                                                      • +1
                                                                                        Не надо представлять, как они должны выглядеть на ассемблере. Надо представлять, что делает процессор, а это таки совсем немножко другое.

                                                                                        В моих задачах плюсов достаточно, чтобы что шину памяти насытить, что иногда Intel IPP обогнать (которые, вероятно, на ассемблере). Иными словами, на ассемблере быстрее работать не будет, а вот писать сильно дольше.
                                                                                        • 0
                                                                                          Производительность IPP оставляет желать, скажу я вам. У меня куча самописных asm-функций быстрее работают, чем их аналоги в IPP.
                                                                                        • +1

                                                                                          Думаю, все хоть раз игрались с компиляцией программы, а потом с декомпиляцией, чтоб посмотреть, как компилятор выкрутился. Так вот, в последние годы он настолько всё оптимизирует, что для понимания получившегося ассемблерного кода нужно знать назубок чуть ли не все команды процессора (а для x86-64 это здоровенная такая куча), да ещё и огромную кучу трюков. Может, конечно, кто-то на такое и способен, я же просто смирился с тем, что компиляторы оптимизируют лучше человека (да и я не видел, чтобы кто-то этот тезис оспаривал).


                                                                                          То о чём вы говорите верно разве что для программирования AVR или MSP430, где горсть команд, и человек может ещё конкурировать с компилятором, и где без ассемблера порой никак.

                                                                                          • +1
                                                                                            Добавлю, что если в прошлом веке системы команд разрабатывались с расчётом, чтобы человеку было удобно писать эффективный ассемблерный код — то сейчас этот фактор вообще не принимается в расчёт. Единственное, что теперь важно при разработке системы команд — смогут ли генерировать эффективный код существующие компиляторы после небольшой доработки.
                                                                                            • –1
                                                                                              Может, конечно, кто-то на такое и способен, я же просто смирился с тем, что компиляторы оптимизируют лучше человека (да и я не видел, чтобы кто-то этот тезис оспаривал).

                                                                                              Я не только оспариваю, но и несколько раз проверял экспериментально. Получается парадоксальный результат — все верно – компилятор компилирует отлично, но все равно, программы на ассемблере получаются быстрее. Дело в том, что человек на ассемблере пишет не так как на ЯВУ (и в этом ошибаются все, которые сравнивают программирование на ассемблер и ЯВУ). Когда пишет на ассемблере, программист выбирает другие алгоритмы, другую архитектуру программы.


                                                                                              Потому что ленивый и выбирает то, что легче написать именно на ассемблере и то что легче будет поддерживаться. Та же самая программа, можно написать и на C/C++, только код будет смотреться совершенно дико и неестественно.


                                                                                              Я проверял все это несколько раз, и всегда результат одинаков. Можете попробовать сами. Надо только писать более менее реальную программу, а не "алгоритм XYZ".

                                                                                              • 0
                                                                                                «В чистую», в абстрактном соревновании человек сливает современным компиляторам по эффективности генерации и эф. генерируемого кода.
                                                                                                Но у человека есть преимущество — знание данных и видение картины в целом, что позволяет иногда отсекать, скажем так, «боковые ветки» в решениях, что-то использовать повторно и так далее.
                                                                                                • 0
                                                                                                  Компилятор безусловно быстрее генерирует ассемблерный код из понятного ему описания алгоритма, чем это делает человек.
                                                                                                  • 0
                                                                                                    Зачем вы повторяете то же самое другими словами?
                                                                                                    • 0
                                                                                                      Просто хотелось убедиться, что мы об одном и том же. Вруг вы считаете, что бинарный код, сделаный компилятором будет быстрее.
                                                                                                      • 0
                                                                                                        Это зависит от того, насколько умел программист на ассемблере, который соревнуется с компилятором, разумеется. Среднего ассемблериста компилятор побьет и в скорости исполняемого кода.
                                                                                                        • 0

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


                                                                                                          Ну и главное. У компилятора есть только один шанс сгенерировать код (если это не JIT). А у програмиста есть возможность написать, потестировать и переписать.


                                                                                                          Хотя вот задумался и стало интересно есть ли сейчас компиляторы на нейросетях или ген. алгоритмах, которые могут медленно и упорото упорно перегенерировать код, пока не достигнут максимальной производительности.

                                                                                                          • 0
                                                                                                            Бывает есть два шанса. См. Intel compiler PGO.
                                                                                                            • 0
                                                                                                              Все верно — человек может итерационно делать код компактнее и бастрее. Но никто не будет этого делать для всех участков — как обычно, серьезно оптимизируется только критичное место. А остальное — используя какие-то best practises. Но и компилятор делает то же самое не хуже (а критичные места мы можем на вставках написать). При этом компилятор, оптимизируя «прочие» места может, скажем, держать в памяти хоть «три страницы» кода и эффективно распределять регистры, в долю секунды делая это лучше, чем будет далть для «прочих мест» человек. Зато человек может применить нестандартную конвенцию вызова и так далее.
                                                                                          • 0
                                                                                            (мимо ветки)
                                                                                            • 0
                                                                                              Часто пишу на 8-битном AVR-ассемблере. Часто встречаются задачи, как на плату в 8мм диаметром встроить, скажем, генератор хитрого сигнала, и 555-х там потребуется минимум три, да с обвесом, а ATtiny13 хватит одного.
                                                                                              В статье же вообще никак не рассмотрены процессоры AVR, особенности avra, да и вообще, гляжу, программирование микроконтроллеров не затронуто.
                                                                                              Как-то мимо…
                                                                                              Программировать на асме под x86 — тот ещё ад, кстати. Я пробовал не раз и проклинал всё.
                                                                                              • 0

                                                                                                Да ладно. x86 еще нормально. x64 — вот это ад.

                                                                                              • 0
                                                                                                В списке источников явно не хватает Агнера нашего Фога (Agner Fog) с его software optimization resources.
                                                                                              • +2
                                                                                                Статься начинается как писать на асм, а по сути рассматривается как обучать.
                                                                                                На мой взгляд учить asm сейчас стоит для всяких ARM Cortex M3 на крайний случай Broadcomm/Raspberry Pi. На PC потребности в нем минимальны. А в embedded — это требование жизни.
                                                                                                x86 особенно, MIPS частично, во встроееной технике проиграли маркетинговую войну ARM. Его и стоит учить.
                                                                                                Keil, gnu asm.
                                                                                                bob.cs.sonoma.edu/IntroCompOrg-RPi/intro-co-rpi.html — интересная книга.
                                                                                                • +1
                                                                                                  На мой взгляд учить asm сейчас стоит для всяких ARM Cortex M3 на крайний случай Broadcomm/Raspberry Pi. На PC потребности в нем минимальны. А в embedded — это требование жизни.

                                                                                                  Три года уже работаю в embedded'е ни разу за всё время ни мне ни кому из коллег не довелось использовать ассемблер, дизассемблер приходилось а вот ассемблер нет. Даже тем кто пишет под AVR. Так что очень преувеличено его необходимость в современном embedded'е.
                                                                                                  Что надо это понимание как будет выполнятся программа на том чипе под который пишешь и каким ботом это может выйти.
                                                                                                  • 0
                                                                                                    На PICах тоже не требуется? Из-за большого разнообразия комбинаций периферии в линейке наверняка кто-то подбирает впритирку под задачу.
                                                                                                    • +1
                                                                                                      Вполне вероятно что где то так и делают. Но там где работаю я обычно сжатые сроки, там не до того чтобы вылизывать всё до байта. На моей памяти был только один проект в котором использовали все ресурсы на 100%, но всё равно в ассемблер не перешли. Слишком дорога получается разработка и поддержка.
                                                                                                      • –1
                                                                                                        На моей памяти был только один проект в котором использовали все ресурсы на 100%, но всё равно в ассемблер не перешли.

                                                                                                        А значит, на 100%, все равно не использовали. :P

                                                                                                  • –1
                                                                                                    Современный embedded уже вплотную подошел к жабаскрипту в качестве единственного инструмента, какой, нафиг, ассемблер? Даже страно, что никто до сих пор не выпустил кристалл с аппаратным декодером/интерпретатором этого скриптового безумия.
                                                                                                    • +1
                                                                                                      Думаю, что всем хватило аппаратной оптимизации под яву.
                                                                                                      • +2
                                                                                                        Java — не первый ЯВУ с аппаратной реализацией:
                                                                                                        Неудивительно, что ни один из «байткод-процессоров» — ни для p-кода, ни для Java — не стал коммерчески успешным. (Сюда же можно отнести и намного более ранний процессор Intel iAPX 432 (1981) — аппаратную реализацию байткода для Ады.) <...> Для того, чтобы «в железе» отслеживать зависимости между данными, распределять их по «железным» регистрам, и переставлять обращения к ним так, чтобы уложиться в «железные» ограничения — требуются очень сложные механизмы. Получается, что при одном и том же уровне полупроводниковых технологий эффективнее создать процессор для простой ISA, и на нём реализовать трансляцию байткода, — чем выполнять этот же байткод «в железе». Вновь и вновь мечтательные айти-предприниматели убеждались, что превратить «универсальный машинный язык» в настоящий — хоть и возможно технически, но коммерчески бесперспективно.
                                                                                                        • 0
                                                                                                          Ну как раз ARM9EJ-S был коммерчески успешным. Мобильников на нем было много. У самого был мобильник c этой технологией. Отличались они от собратьев в 2-3 более шустрой явой.
                                                                                                          • 0
                                                                                                            Если бы Jazelle была коммерчески успешной, то её бы не выпилили из всех последующих чипов, я полагаю?
                                                                                                            Автор книги «Processor Design» считает так же: «These Java-specific processors prompted some interest, but not a lot of enthusiasm.»
                                                                                                            • 0
                                                                                                              Увы, потребитель пропал. Вы когда в последний раз держали в руках кнопочный телефон с поддержкой java? А в смартфонах — JIT-компиляциия, своя VM, они не нуждаются в специальном процессоре. Так что вторая реинкарнация (на Cortex A8) тоже завершилась.

                                                                                                              Так что запилили-выпилили, опять запилили — опять выпилили, запасаемся покорном и ждем третьей реинкарнации.
                                                                                                          • 0
                                                                                                            Что касается ЯВУ с аппаратной реализацией, то если найдете — почитайте «Как паскаль и оберон попадают на Самсон», вот краткое описание. Там сделали взаимную заточку кодогенератора под железа, а железа под кодогенератор.
                                                                                                            • 0
                                                                                                              А как же МИР?
                                                                                                        • +3
                                                                                                          Какое там обучать, если даже в заголовке «The Assembler»?
                                                                                                          Если обучать, тогда надо брать какой нибудь восьмибитный процессор с регистровой адресной парой, чтобы студентам жизнь мёдом не казалась — КР580, Z80, MOS6510. И писать на этом многозадачную операционку с TCP/IP. Без ограничений языка. Хочешь — пиши на С, только компилятор пиши сам…
                                                                                                          Только, боюсь, 70% студентов вылетят нафиг.
                                                                                                          Да и 70% преподавателей тоже…
                                                                                                          • 0
                                                                                                            В Технионе (бывшем в двадцатке лучших CS-факультетов в мире) до сих пор учат ассемблеру PDP-11, просто потому что для него лекции и задания уже составлены и выучены наизусть поколениями преподов, а новые составлять ни у кого руки никак не дойдут.
                                                                                                            Я у тамошних преподов спрашивал, не собираются ли они переводить курс на ARM или на ещё что-нибудь актуальное для практических (embedded) целей. Нет: говорят, что если и будут переводить, то на x86 или x64, просто по причине доступности инструментов разработки и сред выполнения.
                                                                                                            :-(
                                                                                                            • +1
                                                                                                              И они молодцы (кроме шуток). У PDP-11 отличнейший высокоуровневый ассемблер, который даст нормальное понимание как оно вообще всё.
                                                                                                              Не надо готовить ARM (Java/Pascal) программистов в ВУЗах, все будут в пролёте! Уже, в общем-то, кадровый голод. Не языкам студентов учат, и не конкретным ассемблерам, а общим принципам.
                                                                                                              • 0
                                                                                                                1) Неплохо было бы обучать общим принципам на примере чего-нибудь практически применимого, чтобы выигрыш был сразу по обоим фронтам. Ассемблер x86, или ARM, или MIPS какой-нибудь, для обучения общим принципам ничуть не хуже PDP-11, но конспекты по нему не отправятся в мусорку сразу же после экзамена.

                                                                                                                2) Как раз для обучения современным архитектурам — PDP-11, с его сверх-высокоуровневыми инструкциями, довольно нерепрезентативен.
                                                                                                                • 0
                                                                                                                  Люди обычно не понимают чему их обучают, потому, что для того, чтобы задать правильный вопрос нужно знать половину ответа.
                                                                                                                • +2

                                                                                                                  У PDP-11 отличнейший высокоуровневый ассемблер, который даст нормальное понимание как оно вообще всё было 30 лет назад ;)

                                                                                                                  • 0
                                                                                                                    тогда уж лучше msp 430, очень похож на PDP11 и очень актуален
                                                                                                                • 0
                                                                                                                  Ооо, мне на моей первой в жизни работе как юному падавану досталась задача — запилить компилятор для Z80. Было познавательно.
                                                                                                                  • 0
                                                                                                                    У нас использовали ассемблер машины VAX (2010е годы). Но наравне с х86, просто в разных курсах.
                                                                                                                    • 0
                                                                                                                      По дальнейшему размышлению, отличной платформой для обучения новичков ассемблеру/низкоуровневому программированию был бы мегапроцессор — чтобы выполнение машкода сделать буквально осязаемым.
                                                                                                                      Без такого экспоната процессор так и останется чёрным ящиком, в котором волшебные гномики понимают и выполняют инструкции.
                                                                                                                      • +1
                                                                                                                        Офигенная штука.
                                                                                                                        • 0
                                                                                                                          Забавно, темой моей дипломной работы был примитивный эмулятор процессора с перегружаемым на ходу микрокодом, с доступом к нему на всех уровнях и явным параллелизмом. С фактическим доступом к некоторым вентилям на шине. Тоже формально с обучающей целью.
                                                                                                                    • +1
                                                                                                                      почему-то ожидал тут увидеть какую-нибудь модную кросплатформенную замену redasm…
                                                                                                                      • +3
                                                                                                                        В скором времени мы запустим портал с тестами (вопрос – варианты ответа) на знание ассемблера и архитектуры компьютера.

                                                                                                                        Ох всегда меня это раздражало. Знания ассемблера, блин ну вы же сами пишите:
                                                                                                                        Язык ассемблера — символьная форма записи машинного кода, использование которого упрощает написание машинных программ.

                                                                                                                        Ну что значит в таком случае знание ассемблера? Если вы имеете ввиду что это x86 так так и напишите. Но есть ведь ещё ARM, MISP, x51, AVR, Z80, Microbalze, NIOSII, PIC и прочее прочее. Так знания какого ассемблера вы хотите проверять?