Статья посвящена языку ассемблер с учетом актуальных реалий. Представлены преимущества и отличия от ЯВУ, произведено небольшое сравнение компиляторов, скрупулёзно собрано значительное количество лучшей тематической литературы.
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 |
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
- Абель П. Язык Ассемблера для IBM PC и программирования. – М.: Высшая школа, 1992. – 447 с.
- Брэдли Д. Программирование на языке ассемблера для персональной ЭВМ фирмы IBM.– М.: Радио и связь, 1988. – 448 с.
- Галисеев Г.В. Ассемблер IBM PC. Самоучитель.: – М.: Издательский дом «Вильямс», 2004. – 304 с.: ил.
- Дао Л. Программирование микропроцессора 8088. – М.: Мир, 1988. – 357 с.
- Жуков А.В., Авдюхин А.А. Ассемблер. – Спб.: БХВ-Петербург, 2003. – 448 с.: ил.
- Зубков С.В., Ассемблер для DOS, Windows и UNIX. – М.: ДМК Пресс, 2000. – 608 с.: ил. (Серия «Для программистов»).
- Ирвин К. Язык ассемблера для процессоров Intel, 4-е издание.: пер. с англ. – М.: Издательский дом «Вильямс», 2005. – 912 с.: ил. – Парал. тит. англ.(см. также свежее 7-ое издание в оригинале)
- Нортон П., Соухэ Д. Язык ассемблера для IBM PC.– М.: Компьютер, 1992.– 352 с.
- Пильщиков В.Н. Программирование на языке ассемблера IBM PC.– М.: ДИАЛОГ-МИФИ, 1994–2014 288 с.
- Скляров И.С. Изучаем ассемблер за 7 дней www.sklyaroff.ru
Advanced
- Касперски К. Фундаментальные основы хакерства. Искусство дизассемблирования. – М.: СОЛОН-Пресс, 2004. 448 с. – (Серия «Кодокопатель»)
- Касперски К. Техника отладки программ без исходных текстов. – Спб.: БХВ-Петербург, 2005. – 832 с.: ил.
- Касперски К. Компьютерные вирусы изнутри и снаружи. – Спб.: Питер, 2006. – 527 с.: ил.
- Касперски К. Записки исследователя компьютерных вирусов. – Спб.: Питер, 2006. – 316 с.: ил.
- Кнут Д. Искусство программирования, том 3. Сортировка и поиск, 2-е изд.: пер. с англ. – М.: Издательский дом «Вильямс», 2003. – 832 с.: ил. – Парал. тит. англ.
- Колисниченко Д.Н. Rootkits под Windows. Теория и практика программирования «шапок-невидимок», позволяющих скрывать от системы данные, процессы, сетевые соединения. – Спб.: Наука и Техника, 2006. – 320 с.: ил.
- Лямин Л.В. Макроассемблер MASM.– М.: Радио и связь, 1994.– 320 с.: ил.
- Магда Ю. Ассемблер для процессоров Intel Pentium. – Спб.: Питер, 2006. – 410 с.: ил.
- Майко Г.В. Ассемблер для IBM PC.– М.: Бизнес-Информ, Сирин, 1997.– 212 с.
- Уоррен Г. Алгоритмические трюки для программистов, 2-е изд.: пер. с англ. – М.: Издательский дом «Вильямс», 2004. – 512 с.: ил. – Парал. тит. англ.
- Скляров И.С. Искуство защиты и взлома информации. – Спб.: БХВ-Петербург, 2004. – 288 с.: ил.
- Уэзерелл Ч. Этюды для программистов: Пер. с англ. – М.: Мир, 1982. – 288 с., ил.
- Электронная библиотека братьев Фроловых www.frolov-lib.ru
- Чекатов А.А. Использование Turbo Assembler при разработке программ.– Киев: Диалектика, 1995.– 288 с.
- Юров В. Assembler: специальный справочник.– Спб.: Питер, 2001.– 496 с.: ил.
- Юров В. Assembler. Практикум. 2-е изд. – Спб.: Питер, 2006. – 399 с.: ил.
- Юров В. Assembler. Учебник для вузов. 2-е изд. – Спб.: Питер, 2007. – 637 с.: ил.
- Пирогов В. Assembler учебный курс. 2001 Нолидж
- Пирогов В. АССЕМБЛЕР учебный курс 2003 Нолидж-БХВ
- Пирогов В. Assembler для windows
1-ое издание ? М.: изд-во Молгачева С.В., 2002
2-ое издание ? СПб.:. БХВ-Петербург, 2003 ? 684 с.: ил.
3-ье издание ? СПб.:. БХВ-Петербург, 2005 ? 864 с.: ил.
4-ое издание ? СПб.:. БХВ-Петербург, 2012 ? 896 с.: ил. - Пирогов В. Ассемблер на примерах. ? СПб.:. БХВ-Петербург, 2012 ? 416 с.: ил.
- Пирогов В. АССЕМБЛЕР и дизассемблирование. ? СПб.:. БХВ-Петербург, 2006. ? 464 с.: ил.
- Пирогов В. работа над книгой '64-битовое программирование на ассемблере (Windows,Unix)'. В книге рассматривается программирование на fasm в 64-разрядных Windows и Unix
- Юров В., Хорошенко С. Assembler: учебный курс.– Спб.: Питер, 1999. – 672 с.
- Ю-Чжен Лю, Гибсон Г. Микропроцессоры семейства 8086/8088. Архитектура, программирование и проектирование микрокомпьютерных систем.– М.: Радио и связь, 1987.– 512 с.
- Agner Fog: Software optimization resources (assembly/c++) 1996 – 2017. Веб-страница
- Intel ® 64 and IA-32 Architectures Optimization Reference Manual
- Intel ® 64 and IA-32 Architectures Software Developer’s Manual Volume 1: Basic Architecture
- Intel ® 64 and IA-32 Architectures Software Developer’s Manual Volume 2A: Instruction Set Reference, A-M
- Intel ® 64 and IA-32 Architectures Software Developer’s Manual Volume 2B: Instruction Set Reference, N-Z
- Intel ® 64 and IA-32 Architectures Software Developer’s Manual Volume 3A: System Programming Guide, Part 1
- Intel ® 64 and IA-32 Architectures Software Developer’s Manual Volume 3B: System Programming Guide, Part 2
- Leiterman J.C. 32/64-BIT 80x86 Assembly Language Architecture. © 2005, Wordware Publishing, Inc (568 pages) 2320 Los Rios Boulevard Plano, Texas 75074
- Turbo Assembler® Version 3.2 User's Guide Borland International. Inc 1800 Green Hills Road P.O. BOX 660001, Scotts Valley, CA 95067-0001
- Статьи с сайта wasm.in
- Статьи с сайта sasm.narod.ru
- Сайт MASM32 и форум
- Сайт FASM и форум
- Сайт NASM
4. Практика
Итак, вы уже знаете, что такое ассемблер и с чем его едят. Вы запаслись парой/тройкой книг и веб мануалами, возможно определились и с компилятором… К сожалению уроки программирования выходят за рамки данной статьи, но для тех чей выбор пал на MASM/FASM можете воспользоваться следующими макетами:
- MASM64 простое окно masm64SimpleWindow.asm
- FASM64 простое окно fasm64SimpleWindow.asm
Остается открытым вопрос, в каком редакторе писать код? Кто-то пишет в блокноте и компилирует через командную строку, более смекалистые готовят скрипты – упрощая процесс, другие же используют специальные среды разработки. Да, есть IDE и в области низкоуровневого программирования, их обзор также выходит за рамки статьи. Однако пользуясь возможностью, осмелюсь предложить вам попробовать свою среду для программирования на ассемблере – ASM Visual. Кроме базовых возможностей, отличается от аналогов наличием инструментов рефакторинга, метрик кода, в целом более интуитивно понятными интерфейсами и собственным типом проекта.
Желаем вам, друзья, значительных достижений и новых знаний в 2018 году!
С уважением
Михаил Смоленцев MiklIrk (Иркутский государственный университет путей сообщения),
Алексей Гриценко expressrus (Донской государственный технический университет).
Ps1: Уважаемый, Хабрахабр! Добавьте в ваш редактор подсветку ассемблера (Intel-синтаксис), это пригодится для будущих статей!
Ps2: В скором времени мы запустим портал с тестами (вопрос – варианты ответа) на знание ассемблера и архитектуры компьютера. Тесты будут структурированы по уровню сложности. Если вы преподаете ассемблер или имеете достаточные знания в этой области – напишите нам на почту express-rus@yandex.ru вы можете принять участие предложив свой тест в систему.
Комментарии (146)
tidsresenarens
02.01.2018 15:32Говоря про Ирвина, я бы «обновил» издание до 7-го, пусть оно и на английском языке
Daniil1979
02.01.2018 15:33Хех… Я был уверен, что НИКОГДА уже не увижу на Хабре (да и любом другом сайте) статьи про ассемблер.
Вспомнил молодость, ассемблер, Clipper, с чего начинается Родина… В смысле, первые символы dos-овского .exe-файла и первые символы .exe-файла под Windows, как ставили Windows 95 поверх MS-DOS и Windows 3.1, а потом пытались откатиться при помощи установки Windows 3.1… Эх…izzholtik
02.01.2018 16:42+1Ассемблер будет использоваться всегда. Потому что всегда будут микроконтроллеры по $0.2 с килобайтом флэша и тремя с половиной регистрами, которых достаточно для управления микроволновкой.
0xd34df00d
02.01.2018 17:47Под такие микроконтроллеры можно тоже писать на плюсах, есть положительный опыт с attiny. Не микроволновкой, правда, а лазером в экспериментальной установке управляли, но то такое.
izzholtik
02.01.2018 23:47Да без проблем, я под AVR на C++ писал. Сейчас кто угодно эту платформу поддерживает, даже раст.
Daddy_Cool
03.01.2018 07:22Аналогично. Управляем установкой, МК — Atmega какая-то, пишем на С. Наверное можно и на асме, но зачем? На ассемблере написал «Жизнь» — когда на курсах по нему учился и всё.
AllexIn
02.01.2018 18:23В мире, где железо стремительно дешевеет, а программиста — стремительно дорожают ваше утверждение выглядит сомнительным.
VEG
02.01.2018 18:28Дешевеет уже давно не так стремительно как раньше, и со временем будет дешеветь всё меньше.
Впрочем соглашусь, что за исключением очень редких случаев, писать прямо на асме нет смысла.NetBUG
03.01.2018 04:30Ну да, поскольку мы, кажется, уже упёрлись в стоимость пластика и рамки с выводами.
monah_tuk
02.01.2018 20:34Я на ассемблере не пишу, пишу на C++, но знать и понимать его стоит. Как минимум для целей отладки или понимания происходящего под капотом: иногда после этого сильно по другому смотришь на более высокий уровень. Обязательно нужно знакомится с соглашениями по вызовам для вашей платформы и так далее. Особенно это актуально для всякого embedded.
Hokum
02.01.2018 16:00Может быть у вас есть пример из реального проекта, когда вставки на ассемблере существенно дали выигрыш в скорости для десктоп приложения? Или использование ассемблера все таки ограничивается драйверами и узкоспециализированным ПО, где действительно нужно быть уверенным в том, что происходит на уровне процессора? Я не пытаюсь приуменьшить достоинства ассемблера, просто мне кажется, что современные компиляторы оптимизируют код лучше, чем среднестатистический программист сможет написать ассемблере.
Знание ассемблера безусловно полезное, например в случае отладки, когда есть только бинарный код, но насколько целесообразно в прикладном ПО делать вставки на ассемблере?MacIn
02.01.2018 16:03Ну, здесь на Хабре была серия статей — человек написал на языке ассемблера сервер и форум на его основе, поищите.
ValdikSS
02.01.2018 16:16Если говорить про ассемблерные вставки, а не про написание программы полностью на ассемблере, то они в высокопроизводительных программах используются повсеместно: в рендерерах 3D, в видеокодеках, в программах для изменения размеров изображений.
Есть еще противоположная сторона оптимизации: когда нужно уместить код в минимальное количество байт, тогда приходится использовать ассемблер и всякие трюки. Например, декомпрессор в паковщике исполняемых файлов upx написан на ассемблере.
expressrus Автор
02.01.2018 17:19+1Если прям реальный бытовой проект из моего опыта, в системе документооборота были переписаны на асм функции подсчета контрольных сумм файлов и хеширования паролей, что в обоих случаях достаточно заметно снизило время ожидания клиента.
iig
02.01.2018 18:02Ну, не буду сильно спорить..
Возьмем достаточно большой файл.
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 с.
Нехитрый эксперимент показывает, что самое медленное при работе с файлами — дисковый ввод-вывод; его в первую очередь нужно оптимизировать.
4eyes
02.01.2018 18:58Возможно, в высокоуровневом варианте был какой-то алгоритмический просчет, вроде лишних выделений памяти, чтения из файла по байту и т.д?
Вот С++ код умножения на 5 и суммирования 1024 байт из буффера, и я с трудом представляю, каких сил будет стоить написание и сопровождение подобного кода вручную:
godbolt.org/g/2QW1Qxiig
02.01.2018 19:17Так на ассемблере писать никто не будет. С этим замечательно справится компилятор.
Цикл из 1024 сложений и одно умножение на 5 (2 сдвига и сложение) — это как-то более логично.4eyes
02.01.2018 19:40А что ж тогда писать на ассемблере в контексте оптимизации?
iig
02.01.2018 20:20А это смотря что нужно оптимизировать. В смысле написания и поддержки — 2 строки на C++ конечно же, оптимальное решение.
В смысле быстродействия… Напрашивающийся цикл из 1024 сложений выглядит лучше… На 8086 это бы прокатило ;) Но компилятор лучше знает архитектуру процессора, и, подозреваю, что эти странные 128-битные операции неспроста..4eyes
02.01.2018 20:38Напрашивающийся цикл из 1024 сложений выглядит лучше…
Вряд ли он лучше. Работать будет в лучшем случае так же, но скорее всего — медленнее. И дело не только в странных и не очень операциях, а еще и в ветвлениях и затратах на сам цикл.iig
02.01.2018 20:57Да. Если написать коротко и понятно — это будет, скорее всего, неоптимально. А если написать оптимально — будет сложно (а то и невозможно) поддерживать.
Так, в вашем примере, если заменить int на short (или long) — компилятор использует совершенно другие инструкции. Получается, для разных типов данных написанный на ассемблере алгоритм нужно переписывать.
tyomitch
03.01.2018 10:29Нет, даже во времена 8086 для быстродействия приходилось разворачивать циклы, иначе ветвления пожирали всё время выполнения.
4eyes
02.01.2018 19:14Вдогонку к предыдущему сообщению:
… а С++ реализация cosine similarity между одним float-вектором размерностью 192 и 1.7 гигабайтами других таких же векторов с использованием SIMD-intrinsics вычисляется за 0.3 секунды на процессоре Celeron J1900 @ 1.99GHz, на NAS-е, внутри виртуалки.
Не то, чтобы сильно быстро, но это даже не ноутбучный процессор, не самая быстрая память, еще и виртуалка.
lexa
02.01.2018 19:45Обработка изображения в моем/нашем 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 — внутри в плавучке, что несколько улучшает качество теней)
4eyes
02.01.2018 19:47Это не просто «не ассемблер в чистом виде», это Си :)
monah_tuk
02.01.2018 20:39Это даже не сколько Си, это интринсики :)
4eyes
02.01.2018 20:50Так в том-то и посыл, что по-моему, чаще всего ассемблер для задач оптимизиции нужен только для того, чтобы читать код. А писать и проще и лучше на С/С++, используя интринсики там, где это нужно. Главное отличие в том, что программисту не нужно следить за регистрами и адресами.
Возможно, бывают какие-то хитрые алгоритмы, которые очень сложно выразить в C и проще — на языке ассемблера, но я пока не смог представить ничего подобного.
Конечно, бывают задачи, которые проще решаются на ассемблере: первое, что приходит в голову из того, что писал сам — загрузчик в MBR. Но когда речь идет об оптимизации, я подозреваю баг компилятора или ошибку в высокоуровневом коде.monah_tuk
02.01.2018 22:03Так в том-то и посыл...
Полностью согласен.
что приходит в голову из того, что писал сам — загрузчик в MBR
Что удивительно, беглый поиск не показал мне ни одного pureC бутлодера в MBR на Си… Хотя вру: https://www.codeproject.com/Articles/664165/Writing-a-boot-loader-in-Assembly-and-C-Part хотя и тут без вставок никак.
tyomitch
03.01.2018 12:21Более новые архитектуры, чем x86, изначально разрабатываются с учётом того, чтобы загрузчик можно было писать на чистом Си с интринсиками.
Говорить «для загрузчика необходим ассемблер», глядя на x86 — всё равно, что говорить «для завода двигателя необходим кривой стартёр», глядя на 2101.
monah_tuk
03.01.2018 19:11Кстати, вспомнилось: мне однажды нужно было сделать инъекцию: был закрытый код, который вызывался в контексте ISR и ошибочно вызывал функцию логирования (косвенно, через общий код), которая аллоцировала большой буффер на стеке, чем срывала его, будучи запущенной из ISR.
Инъекция заключалась в том, что имя функции логирования подменялось (средствами GCC и линкера) и вместо неё вызывался враппер, который дополнительно делал проверку. Вот врапер оказалось проще написать на ассемблере, используя знание о соглашениях на вызовы, не портя стек (функция была с переменным числом аргументов).
Ну и да, я понимаю, что это костыль. Но решилось автоматом ещё несколько проблем и стало обоснованием более предметно предъявить разработчикам закрытой части SDK.
lexa
03.01.2018 09:48Ну да. Адресную арифметику оставляю компилятору.
Плюс, некоторые компиляторы позволяют себе переупорядочить порядок действий.
Но смысл то один — пишу ровно ассемблерные куски правда на немного птичьем языке
Hokum
02.01.2018 23:41MacIn, acyp спасибо за указания на статьи. Но я имел ввиду пример, когда целесообразно сделать ассемблерные вставки. Вот пишу я некоторое десктопное приложение на C++ и в какой-то момент понимаю, что вот здесь лучше написать на ассемблере. Есть ли такое в современное практике у кого-нибудь? И если да, то какой прирост получился? Понятно, что если захотеть, то можно написать сколь угодно большое приложение на ассемблере, включая многопоточность, работу с сетью и т.д. и т.п. Но хочется не доказательства того что это возможно, а примера когда это было целесообразно. Не холивара ради, а просто из любопытства. Так как я вряд ли смогу написать на ассемблере эффективнее компилятора, но вполне допускаю, что такие люди есть и такие ситуации тоже.
old_bear
03.01.2018 00:03У меня есть вполне обширный опыт по написанию asm-функций для вычислительно-интенсивных частей алгоритмов, с применением simd-ов. Прирост для конкретно этого кода в разы, иногда в десятки раз. Для всего приложения включение оптимизаций даёт прирост в несколько раз. Правда этих оптимизаций в приложении уже довольно много накопилось.
Но это именно отдельные функции, а не вставки asm-а в С-код.Hokum
03.01.2018 00:11Спасибо. Тут еще выше привели пример с инструкциями SSE3, не совсем про ассемблер, но то же интересно.
old_bear
03.01.2018 00:29Интринсики (intrinsics) — неплохая штука, когда нужно быстро объяснить глупому компилятору, как можно сделать при помощи simd-ов что-то относительно простое. Но к сожалению они не дают контроля над регистрами. Даже в том примере, на который вы обратили внимание, нет никаких гарантий, что, например, переменная «xlo» не будет запихнута в стек в промежутке между первой и третьей строчками кода (а это, на минуточку, 32 байта). И такие ситуации частенько возникают, когда количество одновременно используемых simd-регистров (переменных) становится больше 6-8 (при том, что всего их доступно 16 в режиме х86-64).
С другой стороны хорошие компиляторы могут и самостоятельно использовать эффективные simd-инструкции при правильно написанном С-коде и высоком уровне оптимизации. И временами это бывает не менее эффективно, чем использование интринсиков.bibmaster
04.01.2018 03:53С intrinsics ещё такая штука, если поддержку того или иного instruction set надо проверять в runtime, приходится generic/optimized версии функций компилировать отдельно. Или же можно использовать явный вызов через asm. Кстати, о SSE… Не зря например в протоколе Kafka используют CRC32C. Потому что для него есть инструкции в SSE4.2.
0xd34df00d
04.01.2018 18:46+2приходится generic/optimized версии функций компилировать отдельно
Зачем? Есть же атрибуты, вроде__attribute__((target("ssse3")))
для gcc и clang. Можно в одном translation unit держать версии для нескольких SIMD-наборов.
gcc вам даже сам трамплин сгенерирует.
Cheater
03.01.2018 00:45Использование знания ассемблера в C/C++ разработке не ограничивается только переписыванием кусков кода на ассемблере. У меня лично самый частый сценарий использования ассемблера — это смотреть, в какой вообще ассемблерный код компилятор превратил критичный кусок C++ кода. Например заинлайнил ли вызов функции, или статическую константу. Если обнаружен неоптимальный вызов — значит можно пытаться выиграть ещё, причём косвенно (меняя высокоуровневый код), кстати то ещё развлечение по сравнению с переписыванием напрямую на асме.
vdem
04.01.2018 00:06+1Лет ~20 назад в бытность школьником писал свою реализацию графических примитивов для VESA-режимов (с высоким разрешением) на Borland Pascal (я тогда не знал что есть родные BGI драйверы для этих режимов). Вывод работал заметно медленно, особенно линии и окружности. После переписывания этих методов (и еще нескольких оптимизаций) на inline-ассемблер скорость возросла на порядок минимум. Но сейчас компиляторы гораздо умнее.
AlexeiZavjalov
03.01.2018 00:13В драйверах к серьезным ОС, к счастью, почти не встречается ассемблер — все абстрагируется самой ОС и HALами. Там и так все на шаманстве зачастую, из-за специфики работы с железом, а если еще и писать опкодами, то это шаманство еще и станет нечитабельно.
Jef239
03.01.2018 07:17+1Может быть у вас есть пример из реального проекта, когда вставки на ассемблере существенно дали выигрыш в скорости для десктоп приложения?
- Битовый массив. Ассемблерные инструкции позволили напрямую ставить/снимать/проверять бит. То же самое чрез маску — работало прилично медленней.
- Критическая секция для однопроцессорных машин. Работала без переключения в режим ядра для случая, когда вход в критсекцию свободен. Применялась в серверном приложении при одновременной работе 20 тредов. Проблема была в том, что нужно было обращение к регистру FS, которое компилятор не поддерживал
но насколько целесообразно в прикладном ПО делать вставки на ассемблере?
В прикладном не знаю, а в библиотеках такого очень много. Можете полюбоваться на ассемблерную версию memchr из glibc.AnutaU
03.01.2018 10:59Битовый массив. Ассемблерные инструкции позволили напрямую ставить/снимать/проверять бит. То же самое чрез маску — работало прилично медленней.
Хм, мне казалось, что компиляторы умеют генерировать битовые инструкции из обращений к битовым полям.tyomitch
03.01.2018 12:31Конечно умеют: godbolt.org/g/oDZDxw
aleaksah
04.01.2018 00:06На моем опыте под битовыми операциями понимаются следующие конструкции: https://godbolt.org/g/1Ayj7e
В то время как это вполне себе описывается:
mov eax, dword ptr [x]
sub eax, 5
BTR argc, eax
add eax, 7
BTS argc, eax
Jef239
03.01.2018 17:05Конкретно Delphi 5 — не умел. Компиляторы вообще не умеют использовать наборы инструкций, получившие распространение после их написания. :-)
tyomitch
03.01.2018 18:49Напомню, что здесь обсуждают "
какзачем писать на ассемблере в 2018 году", а не «зачем надо было писать на ассемблере в 1999 году, когда компиляторы были глупее, а системы команд — проще».Jef239
03.01.2018 23:41А чем 2018ый год отличается? Вы или ждете, пока выйдет релиз компилятора с поддержкой нужных вам команд — или пишете ассемблерные вставки. Если не боитесь, то на опенсорсных компиляторах можно ещё и нестабильные ночные билды попробовать.
Лично мне больше нравится стабильный проверенный компилятор + ассемблерные вставки, чем экспериментальные версии.
konservs
03.01.2018 07:27Есть пример проекта, когда использование ассемблера дало прирост в энергоэффективности устройств.
В студенческие годы разрабатывал с товарищем АСКУЭ (автоматическая система контроля и учёта электроэнергии). Использование ассемблера и знание режимов работы микроконтроллера позволило запитать 7 кучек (по кучке на подъезд) из 30+ устройств (по устройству на квартиру) очень небольшим блоком питания. Не помню точно потребления, но та что-то в районе микроампер в режиме ожидания и раз в 15 минут при опросе — милиамперы для каждого устройства) Что дало преимущество, когда понадобилось поставить ИБП для всех устройств.
Cooler2
05.01.2018 21:40Есть такие примеры (это десктопные игры): ассемблерные реализации работы с растром и геометрией (особенно на базе MMX/SSE) зачастую дают существенный выигрыш в скорости. Беда правда в том, что такой код привязан к платформе, и не работает на ARM :(
MacIn
02.01.2018 16:02Документация FASM слабая? Простите, но базовая документация, которая идет в стандартной поставке — исчерпывающая.
johnfound
02.01.2018 17:22Я не знаю откуда это пошло, что у FASM документация слабая???
Это не так! FASM ассемблер простой и та документация которая идет в стандартной поставке и вправду исчерпывающая.
expressrus Автор
02.01.2018 17:23У нас с коллегой немного противоречивое мнение. Когда он появиться (а время у него GMT+8) мы придем к общей позиции и обязательно ответим вам, так же в случае чего подредактируем этот момент в статье. Благодарю.
Acuna
02.01.2018 20:44Возможно это и известно вам, но все же, уж коли зашла речь: в избранное можно заносить не только статьи, но и комменты. Сверхполезная вешь, ибо в комментах часто бывает много полезной информации помимо статей. Ну и плюс можно вернуться к обсуждению позднее.
expressrus Автор
03.01.2018 15:07Нет не замечал, спасибо что сказали. FASM кстати поправили.
Acuna
04.01.2018 00:50Вот-вот) Иконка закладки, аналогичная иконке закладки у статей. Просто подумал, что ситуациях подобного рода будет очень удобно добавлять комменты в избранное, дабы в дальнейшем обсудить их с коллегами.
За FASM спасибо, у них ман действительно неплохой.
masai
02.01.2018 16:39Статья посвящена языку ассемблер с учетом актуальных реалий.
К сожалению про язык ассемблера в статье ничего. Да и озаглавить бы её стоило, наверное, «Сравнение ассемблеров», чтобы не вводить людей в заблуждение. По моему мнению, (не могу судить о большинстве) заголовок «Как писать на ассемблере в 2018 году» предполагает, что в статье пойдёт речь о там как писать код на языке ассемблера с учётом современных наборов команд или технологий.
А кто-то реально сейчас пишет на TASM да ещё и для DOS? Устаревшие вузовские курсы не в счёт.
expressrus Автор
02.01.2018 17:20-1Вводная статья, думаю многим хотелось бы больше практики, в следующий раз мы сосредоточимся именно на высказанных вами вопросах. На тасме только поддерживают старые проекты.
glowingsword
02.01.2018 18:00Помню в своём время игрался с FASM и MASM. В качестве IDE использовал RadASM. Давно это было. Последний раз когда имел дело с ASM — использвоал GNU Assembler. В наше время материалов по Asm-тематике мало, народ всё больше к высокоуровневым ЯП тяготеет. Спасибо автору, что занимается просветительской деятельностью по данной тематике в 2018, может кого-то цикл статей по теме заинтересует, и появится новое поколение любителей ассемблера:)
Profi_GMan
02.01.2018 18:26+1Спасибо, что хоть кто-то ещё пишет про ассемблер. Очень мало про ассемблер статей
singular_asm
02.01.2018 19:00FASM для BSD существует.
На flatassembler.net/download.php 4-я ссылка, в описании упоминается OpenBSDexpressrus Автор
02.01.2018 19:00Есть такое дело. Добавили. Благодарю.
johnfound
02.01.2018 19:49Кстати, для MacOS X тоже:
https://board.flatassembler.net/topic.php?t=13413
И конечно для Menuet/KolibriOS и всяких экспериментальных ОС. Вообще, FASM, несмотря на то, что написан на ассемблере, переносится очень легко на всяких ОС. Намного легче чем тот же NASM.
KoCMoHaBT61
02.01.2018 19:21+1Не знаю, как других, а меня уже давненько выбешивают такие статьи… «Как писать на ассемблере в 2018»…
Очевидно, что имеется ввиду The Assembler x86. Не какой-то там ARM9 с его баррел-шифтами (правда, кому они нужны?), не какая-то там SH, и не о разнице между MIPS и Loongson, не об Эльбрусовском чего-то там они придумали, не о сетевых всяких там — об их величестве x86.
Ну, ладно, допустим… Об x86-64… Допустим… Так опять-же не об жонглированием ядрами и атомных инструкциях…
«Я писал на АСМЕ» — ага, да… Вотиманно на «АСМЕ».olartamonov
02.01.2018 21:29правда, кому они нужны?
Гггг. Сегодня сравнивал производительность на Cortex-M3 двух реализаций AES-128 — на C и на асме, в последней как раз barrel shift используется.
Ну, асм быстрее. Меньше, чем в два раза, но быстрее. Ещё б на фоне недостатков кода на нём это кого-нибудь бы в контексте данного проекта волновало бы.
Ardanay
03.01.2018 07:30В целом всё правильно, но можно же было всё тоже самое и без приношения жертв богу сарказма. Не все верят в то что на технической площадке обязательно надо блистать остроумием.
Kobalt_x
02.01.2018 19:57На сайте А.В. Столярова книга по NASM, а у вас в таблице она отнесена к GAS. И если не ошибаюсь, то синтаксис AT&T там только упоминается дальше 5й страницы идет интеловский синтаксис.
DustCn
02.01.2018 20:49Использование ассемблера в вычислительном коде скорее всего приведет к замедлению ваших программ.
«Компактный код» сейчас совершенно не значит «быстрый код».
Писать UI, или IO на ассемблере это практически убивать свое время на скучнейшую работу. Если так уж горит — можно сделать всю обвязку на плюсах или еще чем то, а потом сделать ассемблерную вставку.mapron
02.01.2018 21:12«Использование ассемблера в вычислительном коде скорее всего приведет к замедлению ваших программ.»
Моих — да, любых — нет)
К слову, разработчики видеокодеков по-прежнему активно используют асм. Посмотрите исходные коды libvpx, libx265, libx265, да вообще ffmpeg директории asm.sumanai
02.01.2018 22:40Популярные видеокодеки работают на миллиардах устройств, плюс особенности задачи делают выгодным вложение десятков тысяч человекочасов на разработку. В большинстве же остальных случаев это просто невыгодно, увы.
johnfound
02.01.2018 21:12Использование ассемблера в вычислительном коде скорее всего приведет к замедлению ваших программ.
А вы пробовали? Я да. Несколько раз. И дело в том, что нет, не получается. На ассемблере всегда получается намного быстрее.
На C/C++ можно написать быстрые программы, но дело в том, что надо ясно представлять как они должны выглядеть на ассемблере. А потом обмануть компилятора, чтобы сгенерировать нужный ассемблерский код. Для меня проще написать сразу на ассемблере. :P
0xd34df00d
02.01.2018 21:41Не надо представлять, как они должны выглядеть на ассемблере. Надо представлять, что делает процессор, а это таки совсем немножко другое.
В моих задачах плюсов достаточно, чтобы что шину памяти насытить, что иногда Intel IPP обогнать (которые, вероятно, на ассемблере). Иными словами, на ассемблере быстрее работать не будет, а вот писать сильно дольше.old_bear
02.01.2018 23:23Производительность IPP оставляет желать, скажу я вам. У меня куча самописных asm-функций быстрее работают, чем их аналоги в IPP.
masai
04.01.2018 11:56Думаю, все хоть раз игрались с компиляцией программы, а потом с декомпиляцией, чтоб посмотреть, как компилятор выкрутился. Так вот, в последние годы он настолько всё оптимизирует, что для понимания получившегося ассемблерного кода нужно знать назубок чуть ли не все команды процессора (а для x86-64 это здоровенная такая куча), да ещё и огромную кучу трюков. Может, конечно, кто-то на такое и способен, я же просто смирился с тем, что компиляторы оптимизируют лучше человека (да и я не видел, чтобы кто-то этот тезис оспаривал).
То о чём вы говорите верно разве что для программирования AVR или MSP430, где горсть команд, и человек может ещё конкурировать с компилятором, и где без ассемблера порой никак.
tyomitch
04.01.2018 16:17+1Добавлю, что если в прошлом веке системы команд разрабатывались с расчётом, чтобы человеку было удобно писать эффективный ассемблерный код — то сейчас этот фактор вообще не принимается в расчёт. Единственное, что теперь важно при разработке системы команд — смогут ли генерировать эффективный код существующие компиляторы после небольшой доработки.
johnfound
04.01.2018 17:32-1Может, конечно, кто-то на такое и способен, я же просто смирился с тем, что компиляторы оптимизируют лучше человека (да и я не видел, чтобы кто-то этот тезис оспаривал).
Я не только оспариваю, но и несколько раз проверял экспериментально. Получается парадоксальный результат — все верно – компилятор компилирует отлично, но все равно, программы на ассемблере получаются быстрее. Дело в том, что человек на ассемблере пишет не так как на ЯВУ (и в этом ошибаются все, которые сравнивают программирование на ассемблер и ЯВУ). Когда пишет на ассемблере, программист выбирает другие алгоритмы, другую архитектуру программы.
Потому что ленивый и выбирает то, что легче написать именно на ассемблере и то что легче будет поддерживаться. Та же самая программа, можно написать и на C/C++, только код будет смотреться совершенно дико и неестественно.
Я проверял все это несколько раз, и всегда результат одинаков. Можете попробовать сами. Надо только писать более менее реальную программу, а не "алгоритм XYZ".
MacIn
04.01.2018 18:43«В чистую», в абстрактном соревновании человек сливает современным компиляторам по эффективности генерации и эф. генерируемого кода.
Но у человека есть преимущество — знание данных и видение картины в целом, что позволяет иногда отсекать, скажем так, «боковые ветки» в решениях, что-то использовать повторно и так далее.
m0Ray
02.01.2018 22:09Часто пишу на 8-битном AVR-ассемблере. Часто встречаются задачи, как на плату в 8мм диаметром встроить, скажем, генератор хитрого сигнала, и 555-х там потребуется минимум три, да с обвесом, а ATtiny13 хватит одного.
В статье же вообще никак не рассмотрены процессоры AVR, особенности avra, да и вообще, гляжу, программирование микроконтроллеров не затронуто.
Как-то мимо…
Программировать на асме под x86 — тот ещё ад, кстати. Я пробовал не раз и проклинал всё.
old_bear
02.01.2018 23:17В списке источников явно не хватает Агнера нашего Фога (Agner Fog) с его software optimization resources.
stoune
02.01.2018 23:56Статься начинается как писать на асм, а по сути рассматривается как обучать.
На мой взгляд учить 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 — интересная книга.VBKesha
03.01.2018 01:26На мой взгляд учить asm сейчас стоит для всяких ARM Cortex M3 на крайний случай Broadcomm/Raspberry Pi. На PC потребности в нем минимальны. А в embedded — это требование жизни.
Три года уже работаю в embedded'е ни разу за всё время ни мне ни кому из коллег не довелось использовать ассемблер, дизассемблер приходилось а вот ассемблер нет. Даже тем кто пишет под AVR. Так что очень преувеличено его необходимость в современном embedded'е.
Что надо это понимание как будет выполнятся программа на том чипе под который пишешь и каким ботом это может выйти.Gryphon88
03.01.2018 03:25На PICах тоже не требуется? Из-за большого разнообразия комбинаций периферии в линейке наверняка кто-то подбирает впритирку под задачу.
VBKesha
03.01.2018 12:45+1Вполне вероятно что где то так и делают. Но там где работаю я обычно сжатые сроки, там не до того чтобы вылизывать всё до байта. На моей памяти был только один проект в котором использовали все ресурсы на 100%, но всё равно в ассемблер не перешли. Слишком дорога получается разработка и поддержка.
johnfound
03.01.2018 13:13На моей памяти был только один проект в котором использовали все ресурсы на 100%, но всё равно в ассемблер не перешли.
А значит, на 100%, все равно не использовали. :P
quwy
03.01.2018 02:38Современный embedded уже вплотную подошел к жабаскрипту в качестве единственного инструмента, какой, нафиг, ассемблер? Даже страно, что никто до сих пор не выпустил кристалл с аппаратным декодером/интерпретатором этого скриптового безумия.
Jef239
03.01.2018 07:25Думаю, что всем хватило аппаратной оптимизации под яву.
tyomitch
03.01.2018 10:40Java — не первый ЯВУ с аппаратной реализацией:
Неудивительно, что ни один из «байткод-процессоров» — ни для p-кода, ни для Java — не стал коммерчески успешным. (Сюда же можно отнести и намного более ранний процессор Intel iAPX 432 (1981) — аппаратную реализацию байткода для Ады.) <...> Для того, чтобы «в железе» отслеживать зависимости между данными, распределять их по «железным» регистрам, и переставлять обращения к ним так, чтобы уложиться в «железные» ограничения — требуются очень сложные механизмы. Получается, что при одном и том же уровне полупроводниковых технологий эффективнее создать процессор для простой ISA, и на нём реализовать трансляцию байткода, — чем выполнять этот же байткод «в железе». Вновь и вновь мечтательные айти-предприниматели убеждались, что превратить «универсальный машинный язык» в настоящий — хоть и возможно технически, но коммерчески бесперспективно.
Jef239
03.01.2018 16:52Ну как раз ARM9EJ-S был коммерчески успешным. Мобильников на нем было много. У самого был мобильник c этой технологией. Отличались они от собратьев в 2-3 более шустрой явой.
tyomitch
03.01.2018 18:55Если бы Jazelle была коммерчески успешной, то её бы не выпилили из всех последующих чипов, я полагаю?
Автор книги «Processor Design» считает так же: «These Java-specific processors prompted some interest, but not a lot of enthusiasm.»Jef239
04.01.2018 01:13Увы, потребитель пропал. Вы когда в последний раз держали в руках кнопочный телефон с поддержкой java? А в смартфонах — JIT-компиляциия, своя VM, они не нуждаются в специальном процессоре. Так что вторая реинкарнация (на Cortex A8) тоже завершилась.
Так что запилили-выпилили, опять запилили — опять выпилили, запасаемся покорном и ждем третьей реинкарнации.
Jef239
03.01.2018 17:00Что касается ЯВУ с аппаратной реализацией, то если найдете — почитайте «Как паскаль и оберон попадают на Самсон», вот краткое описание. Там сделали взаимную заточку кодогенератора под железа, а железа под кодогенератор.
KoCMoHaBT61
03.01.2018 07:08Какое там обучать, если даже в заголовке «The Assembler»?
Если обучать, тогда надо брать какой нибудь восьмибитный процессор с регистровой адресной парой, чтобы студентам жизнь мёдом не казалась — КР580, Z80, MOS6510. И писать на этом многозадачную операционку с TCP/IP. Без ограничений языка. Хочешь — пиши на С, только компилятор пиши сам…
Только, боюсь, 70% студентов вылетят нафиг.
Да и 70% преподавателей тоже…tyomitch
03.01.2018 10:48В Технионе (бывшем в двадцатке лучших CS-факультетов в мире) до сих пор учат ассемблеру PDP-11, просто потому что для него лекции и задания уже составлены и выучены наизусть поколениями преподов, а новые составлять ни у кого руки никак не дойдут.
Я у тамошних преподов спрашивал, не собираются ли они переводить курс на ARM или на ещё что-нибудь актуальное для практических (embedded) целей. Нет: говорят, что если и будут переводить, то на x86 или x64, просто по причине доступности инструментов разработки и сред выполнения.
:-(KoCMoHaBT61
03.01.2018 11:35И они молодцы (кроме шуток). У PDP-11 отличнейший высокоуровневый ассемблер, который даст нормальное понимание как оно вообще всё.
Не надо готовить ARM (Java/Pascal) программистов в ВУЗах, все будут в пролёте! Уже, в общем-то, кадровый голод. Не языкам студентов учат, и не конкретным ассемблерам, а общим принципам.tyomitch
03.01.2018 12:431) Неплохо было бы обучать общим принципам на примере чего-нибудь практически применимого, чтобы выигрыш был сразу по обоим фронтам. Ассемблер x86, или ARM, или MIPS какой-нибудь, для обучения общим принципам ничуть не хуже PDP-11, но конспекты по нему не отправятся в мусорку сразу же после экзамена.
2) Как раз для обучения современным архитектурам — PDP-11, с его сверх-высокоуровневыми инструкциями, довольно нерепрезентативен.KoCMoHaBT61
03.01.2018 13:57Люди обычно не понимают чему их обучают, потому, что для того, чтобы задать правильный вопрос нужно знать половину ответа.
iig
03.01.2018 14:22+1У PDP-11 отличнейший высокоуровневый ассемблер, который даст нормальное понимание как оно вообще всё было 30 лет назад ;)
AnutaU
03.01.2018 10:58Ооо, мне на моей первой в жизни работе как юному падавану досталась задача — запилить компилятор для Z80. Было познавательно.
MacIn
03.01.2018 18:47У нас использовали ассемблер машины VAX (2010е годы). Но наравне с х86, просто в разных курсах.
tyomitch
04.01.2018 17:04По дальнейшему размышлению, отличной платформой для обучения новичков ассемблеру/низкоуровневому программированию был бы мегапроцессор — чтобы выполнение машкода сделать буквально осязаемым.
Без такого экспоната процессор так и останется чёрным ящиком, в котором волшебные гномики понимают и выполняют инструкции.MacIn
04.01.2018 18:45Забавно, темой моей дипломной работы был примитивный эмулятор процессора с перегружаемым на ходу микрокодом, с доступом к нему на всех уровнях и явным параллелизмом. С фактическим доступом к некоторым вентилям на шине. Тоже формально с обучающей целью.
Godless
03.01.2018 01:30почему-то ожидал тут увидеть какую-нибудь модную кросплатформенную замену redasm…
VBKesha
03.01.2018 01:32В скором времени мы запустим портал с тестами (вопрос – варианты ответа) на знание ассемблера и архитектуры компьютера.
Ох всегда меня это раздражало. Знания ассемблера, блин ну вы же сами пишите:
Язык ассемблера — символьная форма записи машинного кода, использование которого упрощает написание машинных программ.
Ну что значит в таком случае знание ассемблера? Если вы имеете ввиду что это x86 так так и напишите. Но есть ведь ещё ARM, MISP, x51, AVR, Z80, Microbalze, NIOSII, PIC и прочее прочее. Так знания какого ассемблера вы хотите проверять?
malishich
03.01.2018 07:34Сам писал на FASM, Очень удобная штука. Одна библиотека для x86-64, до сих пор используется в продакшине. Кстати, автору на заметку, FASM также поддерживает ARM. А еще у Томаса есть версия FASM G которая более продвинута, и способна собирать «x86, x64, 8052, AVR, or Java Virtual Machine». Думаю это стоит указать.
VEG
03.01.2018 10:16FASMG в принципе можно обучить собирать под любую платформу, потому что набор инструкций там — это просто макросы. То есть x86 и всё остальное там реализовано просто наборами макросов. PE-файлы и таблицы релоков тоже формируются на макросах.
MacIn
03.01.2018 18:49И макросы FASMа — это реально круто, такой гибкости можно завидовать. Можно пересобрать файл на его макросах, например. Сделать работу за компоновщик т.е.
we1
03.01.2018 09:16А мне несколько лет назад очень нравилось на masm32 делать мелкие утилитки. Да, возни с WinAPI немало (не то что под DOS), но зато обращение к памяти проще, не надо запариваться с типами переменных, это даже удобнее Си.
Конечно, в основном это мелкие вещи, которые один раз пишутся как шаблон, а потом нужные переменные подставляются (в памяти что-нибудь подправить, запускалку с закрытием ненужных окон сделать и т.п.). Но для этого уже давно инструменты есть и тоже вроде как смысл теряется.
Мне больше интересно, как сейчас дела обстоят (и обстоят ли) с программированием под FreeDOS или что-то подобное. Там ведь ассемблер вполне себе удобен (особенно для резидентных программ).johnfound
03.01.2018 09:39Мне больше интересно, как сейчас дела обстоят (и обстоят ли) с программированием под FreeDOS или что-то подобное. Там ведь ассемблер вполне себе удобен (особенно для резидентных программ).
Работать под (Free)DOS не имеет никакого смысла, потому что просто нельзя использовать возможности компьютера. А вот в Linux программировать на ассемблере очень просто. Почти как в DOS.
longtolik
03.01.2018 10:30Спасибо за тему. Хотелось бы также увидеть материалы, описывающие красоту программирования на ассемблере и для чего он, собственно говоря, нужен. Например, как в статье «Программные трюки на ассемблере» из журнала «Микропроцессорные средства и системы». Про рекурсию, реентерабельность программ и про сопрограммы, по-моему, интересно хотя бы для общего развития.
Сравнение ассемблеров/архитектур — когда-то ассемблер DEC мне казался самым лучшим (там архитектура позволяла циклы чтение-модификация-запись при работе с памятью), потом было разочарование от ассемблера для Intel x86 (тут надо делать операции через регистр-аккумулятор AX/EAX и, если уж мы читаем слева-направо, то почему надо писать MOV DX,200, а не MOV 200,DX?). Позже, на Palm III познакомился с ассемблером Pila для Motorola 68000 — вот где красивая архитектура!
Еще интересно было бы узнать про самомодифицирующийся код (и про то, что его нельзя уже изменить, когда попал в конвейер команд/данных, что может быть использовано для определения, что ваша программа прогоняется под отладчиком.
Также можно было бы включить в будущие статьи, например, проект из блога компании Intel, в котором в приложение для Android вставлен и работает программа на Ассемблере. То есть, получается, мы можем писать на Ассемблере для Android! Ну, хотя бы чуть-чуть, для native библиотек.
Еще вопрос: есть книга П.Брамм, Д.Брамм «Микропроцессор 80386 и его программирование». В ней описаны, в частности, дескрипторы страниц и перевод процессора в защищенный режим. Не понятно (простите за невежество), если ОС переводит процессор в защищенный режим и участки памяти вообще не видны для приложений пользователя, то как тогда вирусы могут туда проникнуть? Возможно, меняя код в BIOS или на загрузочном диске.
Для ARM Ассемблера хотелось бы узнать, как включать/останавливать ядра.
some_name
03.01.2018 15:11Как методичку прочитал.
Но если человек пишет на ассемблере, он уже не имеет готовых функций типа printf(), в которых за него продумано, как «общаться» с системой, и должен делать это сам.
Писал вот такой вот код на третьем курсе (MASM):
includelib D:\masm32\lib\kernel32.lib
ExitProcess PROTO, :DWORD
GetStdHandle Proto, :DWORD
Sleep PROTO, :DWORD
WriteConsoleA PROTO, handle: DWORD, lpBuffer:PTR BYTE, nNumberOfBytesToWrite:DWORD, lpNumberOfBytesWritten:PTR DWORD, lpReserved:DWORD
ReadConsoleA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
.data
STD_OUTPUT_HANDLE EQU -11
STD_INPUT_HANDLE EQU -10
coh dd ? ;store console output handle here
cih dd ? ;store console input handle here
.code
ReadingCA proc msg:DWORD, col:DWORD
sub esp,8
push STD_INPUT_HANDLE
call GetStdHandle
mov [ebp-4],eax ;Local Variable for this subroutine
push 0
lea eax,[ebp-8]
push eax
push [ebp+12]
push [ebp+8]
push [ebp-4]
call ReadConsoleA
ret 8
ReadingCA endp
Так что WinAPI использовать возможно.
fukkit
03.01.2018 23:51«Как» писать — это ерунда. Как и во все предыдущие годы: запасшись спеками, кофеином/никотином и парой бесконечных жизней. А вот «когда» и «зачем» — те ещё вопросы.
ZyXI
А ещё в природе есть такая вещь, как i386 в корпусе PQFP. У нас под него писали на ассемблере, потому что nasm может сразу выдать Intel hex, содержащий только нашу программу, а возиться для получения аналогичного результата на C никому не хотелось.
izzholtik
визуально это довольно просто…
не факт, что я прав, конечно.
ZyXI
На работе у меня Windows (7, WSL нету), там не ELF’ы и objcopy есть разве что в cygwin (у меня тоже установлен). И вряд ли всё так просто: нужно разместить безусловный переход по строго определённому адресу (вектора прерываний), а сама программа должна быть по нулевому адресу. И ещё к аргументам нужно добавить, как минимум,
-march=i386 -static -Os
. И нужно понять как записывать и считывать регистры специального назначения. Разобраться можно, но зачем?Помимо этого написание программы на ассемблере позволило использовать «память» в режиме «только чтение», обошедшись без стека и без собственно реализации записи в память — самой памяти в системе никогда не было, была имитация на FPGA, которую тоже нужно написать.
MacIn
Fasm тоже прекрасно выдает чистый бинарник.
ZyXI
Не понимаю, к чему этот комментарий. Если какой?то *asm не способен выдавать «чистый бинарник», то зачем он вообще нужен?
MacIn
К тому что из ряда ассемблеров вы не можете получить ничего, кроме, скажем, .exe без дополнительных утилит.
johnfound
скорее всего и не .exe а .obj
MacIn
Да, но это уже деталь. На Fasm много проще создать код «вне формата».
johnfound
Конечно, на то он и FASM. ;)