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

Статья посвящена языку ассемблер с учетом актуальных реалий. Представлены преимущества и отличия от ЯВУ, произведено небольшое сравнение компиляторов, скрупулёзно собрано значительное количество лучшей тематической литературы.
1. Язык. Преимущества и отличия от ЯВУ
Ассемблер (Assembly) — язык программирования, понятия которого отражают архитектуру электронно-вычислительной машины. Язык ассемблера — символьная форма записи машинного кода, использование которого упрощает написание машинных программ. Для одной и той же ЭВМ могут быть разработаны разные языки ассемблера. В отличие от языков высокого уровня абстракции, в котором многие проблемы реализации алгоритмов скрыты от разработчиков, язык ассемблера тесно связан с системой команд микропроцессора. Для идеального микропроцессора, у которого система команд точно соответствует языку программирования, ассемблер вырабатывает по одному машинному коду на каждый оператор языка. На практике для реальных микропроцессоров может потребоваться несколько машинных команд для реализации одного оператора языка.
Язык ассемблера обеспечивает доступ к регистрам, указание методов адресации и описание операций в терминах команд процессора. Язык ассемблера может содержать средства более высокого уровня абстракции: встроенные и определяемые макрокоманды, соответствующие нескольким машинным командам, автоматический выбор команды в зависимости от типов операндов, средства описания структур данных. Главное достоинство языка ассемблера — «приближенность» к процессору, который является основой используемого программистом компьютера, а главным неудобством — слишком мелкое деление типовых операций, которое большинством пользователей воспринимается с трудом. Однако язык ассемблера в значительно большей степени отражает само функционирование компьютера, чем все остальные языки.
И хотя драйвера и операционные системы сейчас пишут на Си, но Си при всех его достоинствах — язык высокого уровня абстракции, скрывающий от программиста различные тонкости и нюансы железа, а ассемблер — язык низкого уровня абстракции, прямо отражающий все эти тонкости и нюансы.
Для успешного использования ассемблера необходимы сразу три вещи:
- знание синтаксиса транслятора ассемблера, который используется (например, синтаксис MASM, FASM и GAS отличается), назначение директив языка ассемблер (операторов, обрабатываемых транслятором во время трансляции исходного текста программы);
- понимание машинных инструкций, выполняемых процессором во время работы программы;
- умение работать с сервисами, предоставляемыми операционной системой — в данном случае это означает знание функций Win32 API. При работе с языками высокого уровня очень часто к API системы программист прямо не обращается; он может даже не подозревать о его существовании, поскольку библиотека языка скрывает от программиста детали, зависящие от конкретной системы. Например, и в Linux, и в Windows, и в любой другой системе в программе на Си/Си++ можно вывести строку на консоль, используя функцию printf() или поток cout, то есть для программиста, использующего эти средства, нет разницы, под какую систему делается программа, хотя реализация этих функций будет разной в разных системах, потому что API систем очень сильно различается. Но если человек пишет на ассемблере, он уже не имеет готовых функций типа printf(), в которых за него продумано, как «общаться» с системой, и должен делать это сам.
Оптимальной можно считать программу, которая работает правильно, по возможности быстро и занимает, возможно, малый объем памяти. Кроме того, ее легко читать и понимать; ее легко изменить; ее создание требует мало времени и незначительных расходов. В идеале язык ассемблера должен обладать совокупностью характеристик, которые бы позволяли получать программы, удовлетворяющие как можно большему числу перечисленных качеств.
На языке ассемблера пишут программы или их фрагменты в тех случаях, когда критически важны:
- объем используемой памяти (программы-загрузчики, встраиваемое программное обеспечение, программы для микроконтроллеров и процессоров с ограниченными ресурсами, вирусы, программные защиты и т.п.);
- быстродействие (программы, написанные на языке ассемблера выполняются гораздо быстрее, чем программы-аналоги, написанные на языках программирования высокого уровня абстракции. В данном случае быстродействие зависит от понимания того, как работает конкретная модель процессора, реальный конвейер на процессоре, размер кэша, тонкостей работы операционной системы. В результате, программа начинает работать быстрее, но теряет переносимость и универсальность).
Языки программирования высокого уровня абстракции разрабатывались с целью возможно большего приближения способа записи программ к привычным для пользователей компьютеров тех или иных форм записи, в частности математических выражений, а также чтобы не учитывать в программах специфические технические особенности отдельных компьютеров. Язык ассемблера разрабатывается с учетом специфики процессора, поэтому для грамотного написания программы на языке ассемблера требуется, в общем, знать архитектуру процессора используемого компьютера. Однако, имея в виду преимущественное распространение 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 и так далее). Такие конструкции могут облегчить обучение ассемблеру и помогают написать более читаемый код. В некоторые ассемблеры встроены «высокоуровневые конструкции» с ограниченными возможностями. Другие предоставляют высокоуровневые конструкции на уровне макросов.
Никакой ассемблер не заставляет вас использовать какие-либо структуры управления или типы данных высокого уровня, если вы предпочитаете работать на уровне кодировки машинных команд. Высокоуровневые конструкции ― это расширение базового машинного языка, которое вы можете использовать, если найдете их удобными.
Качество документации
Удобство использования ассемблера напрямую связано с качеством его документации. Учитывая объем работы, который тратится для создания диалекта ассемблера, созданием документации для этого диалекта авторы компиляторов практически не заморачиваются. Авторы, расширяя свой язык, забывают документировать эти расширения.
В следующей таблице описывается качество справочного руководства ассемблера, которое прилагается к продукту:
Учебники и учебные материалы
Документация на самом ассемблере, конечно, очень важна. Еще больший интерес для новичков и других, изучающих язык ассемблера (или дополнительные возможности данного ассемблера), ― это наличие документации за пределами справочного руководства для языка. Большинство людей хотят, чтобы учебник, объясняющий, как программировать на ассемблере, не просто предоставляет синтаксис машинных инструкций и ожидает, что читателю объяснят, как объединять эти инструкции для решения реальных проблем.
MASM является лидером среди огромного объема книг, описывающих, как программировать на этом диалекте. Есть десятки книг, которые используют MASM в качестве своего ассемблера для обучения ассемблеру.
Большинство учебников по ассемблеру MASM/TASM продолжают обучать программированию под MS-DOS. Хотя постепенно появляются учебники, которые обучают программированию в Windows и Linux.
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 80×86 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
Желаем вам, друзья, значительных достижений и новых знаний в 2018 году!
С уважением
Михаил Смоленцев MiklIrk (Иркутский государственный университет путей сообщения),
Алексей Гриценко expressrus (Донской государственный технический университет).
Ps1: Уважаемый, Хабрахабр! Добавьте в ваш редактор подсветку ассемблера (Intel-синтаксис), это пригодится для будущих статей!
Учебный курс. Урок 1. Необходимые инструменты
Учиться программировать начнем с процессора Intel 8086. Будем писать программы под DOS Программирование под Windows и Linux сложнее, а нам надо с чего-то начинать. Поэтому начнем с простого и понятного 16-битного процессора 8086.
Практическая ценность от программирования под DOS в наше время не очень большая, если вы, конечно, не собираетесь тесно работать с этой операционной системой. Но она позволит нам быстро освоить основы ассемблера, а потом мы уже перейдем к программированию под 32-битные системы.
Выбор компилятора
Для программирования на ассемблере нам прежде всего необходим компилятор. Наиболее известные компиляторы это TASM, MASM и FASM. В моем учебном курсе я буду использовать FASM. Это довольно новый, удобный, быстро развивающийся компилятор ассемблера, написанный на себе самом Его преимущества — это поддержка сложных макросов и мультиплатформенность. Есть версии под DOS, Windows и Linux.
С его помощью можно сгенерировать файл любого формата, не обязательно исполняемый файл, так что FASM — это превосходный инструмент для экспериментов и исследований.
Сложность в том, что сегодня большинство операционных систем даже на телефонах имеет 64-битную разрядность. В силу особенностей архитектуры просто так запустить 32-разрядную программу DOS на 64-битной системе не получится.
Эмуляция 32-битного DOS в 64-битной среде. DOSBox
Тем, кто работает в 32-битной системе Windows могут просто использовать fasm под Windows для написания и компиляции программ. В этом случае все программы учебного курса вы сможете запустить под Windows. Конечно, реально они будут работать в эмуляторе DOS, в режиме виртуального процессора 8086. Но для учебных целей это вполне подойдёт.
Ну а как же быть тем, кто идёт в ногу с цивилизацией и работает в 64-битной среде? Поскольку писать пограммы для 64 битного процессора нам еще рано, потребуется как-то эмулировать среду 32-битного DOS, к примеру, можно установить виртуальную машину, на неё поставить Windows XP 32-бит или последнюю версию MS-DOS, но предлогаю поступить проще и обойтись эмулятором DOSBox.
С оффициального сайта вы можете скачать DOSBox последней версии. Установите его, следуя инструкциям установщика и для удобства на тот же раздел диска, где находится fasm. Ярлык запуска эмулятора DOSBox появился на рабочем столе. Готово!
Ну или почти, поскольку попытка скомпилировать программу внутри fasm запущенном на DOSBox из коробки обернется неудачей. Причина в том, что DOSBox ориентирован в первую очередь на любителей ретроигр.

Редактирование dosbox.conf
Не будем огорчаться, что разработчики эмулятора обошли поддержку 32-битного реального режима (FRM mode). Мы можем получить нужный результат, перед вызовом fasm загрузив DPMI сервер. Скачайте cwsdpmi по ссылке с моего сайта. Распакуйте архив туда, куда вы ранее установили fasm. В итоге путь к CWSDPMI будет иметь вид C:\fasm\CWSDPMI.
Где писать на ассемблере
Итак, сначала небольшое введение, посвященное тому, зачем мне (в частности) вообще нужно IDE. Дело в том, что наличие IDE практически необязательно для проектов с небольшим размером. Под проектами с небольшим размером я подразумеваю проекты с количеством строк, меньшим 1000. Как правило такая программа состоит из одного файла (или один .asm и один .inc) и содержит 10-15 процедур, столько же структур, макросов, глобальных переменных и констант. Для работы над таким проектом вполне достаточно даже Notepad-а, а компиляцию запускать из bat файла. Все эти элементы программы достаточно легко запоминаются в голове и их применение практически не вызывает никаких трудностей, в худшем случае придется прокрутить текст, посмотреть название или элемент структуры и вернутся к коду. Насчет NotePad-а, это, конечно, утрированно, и подразумевается, что с этим заданием справится любой текстовый редактор. Выбор такого рода редакторов достаточно широкий. Все они, как правило, поддерживают настраиваемую подсветку синтаксиса, возможность запуска внешних приложений и захват текста, возвращаемого компилятором. Для таких целей я предпочитаю использовать UltraEdit (www.ultraedit.com). Почему? Кроме всего вышеперечисленного меня устраивает его компактность, скорость работы, удобные поиск и замена, возможность показа названий процедур (настраиваемая). На этом работы с небольшими проектами я касаться не буду.
2. Требования в IDE
Перейдем к более интересному, а именно большим проектам. Традиционно считается, что на ассемблере сейчас большие проекты не пишутся (или вообще ничего не пишется). А мне, например, нравится и у меня есть несколько проектов с количеством строк, большим 10 000 у каждого. Причем менять язык я не планирую, а число проектов — только увеличивать. Кроме этого каждый мой большой проект (незавершенный, кстати) имеет порядка 300 процедур, примерно такое же количество структур и глобальных переменных и дюжина макросов. При этом каждая процедура имеет 5-10 локальных переменных и 1-3 структуры. Все это разбросано по 5-6 asm-файлам и такому же количеству inc-файлов. Ну, и как прикажете этим хозяйством управлять? Самое время подумать о выборе IDE для управления такого ассорти.
Но прежде я попытаюсь сформулировать те требования, которые я предъявляю к такой системе, в которой мне (лично) было бы удобно работать. В принципе, ничего сверх экстраординарного я не требую. Все ниже перечисленное идет в том порядке, в котором приходит в голову по мере написания, а не по степени важности. Для удобства я разобью эти требованию на группы:
1. Редактор текста.
1.1 Возможность настроить размер, стиль и имя шрифта. Я, например, предпочитаю все писать шрифтом Courier New, 14, bold;
1.2 Настраиваемая подсветка синтаксиса;
1.3 Возможность автозаполнения — выпадающая подсказка во время впечатывания символов. В саму подсказку должны входить ВСЕ глобальные переменные, процедуры, структуры, константы и все локальные для данной процедуры;
1.4 При наведении (клике) на переменную/константу/структуру/макрос/процедуру хотелось бы видеть ее во вспомогательном/всплывающем окне.
1.5 Желательно отделять цветом/стилем шрифта локальные переменные, глобальные и пр.
1.6 Неплохо (хотя и не критично для меня) было бы «сворачивать» процедуры и структуры.
1.6 Про прочие св-ва, присутствующие редакторам, типа настраиваемой табуляции и пр. даже неудобно напоминать.
2. Работа с проектами.
2.1 Удобство при добавлении и удалении файлов проекта (пофайловое добавление — это неудобство);
2.2 Возможность индивидуальных настроек у каждого проекта;
2.3 Копирование св-в одного проекта другому, наследование св-в
3. Непосредственно IDE
3.1 Отображение дерева из глобальных процедур, переменных, структур и констант с удобным поиском не только по первым символам (у меня многие процедуры начинаются одинаково);
3.2 Т.к. компилятор и линкер у masm консольный, то IDE должно захватывать результат компиляции и парсить его для того, чтобы в случае ошибки я мог перейти на нее одним кликом;
3.3 Удобная настройка запуска внешних приложений (отладчика например) с присвоением кнопки на тулбаре и сочетания клавиш;
3.4 Удобное создание и использование репозитария кода (хотя мне не очень важно);
3.5 Поддержка средств контроля версий;
3.6 Интерфейс для написания плагинов;
3.7 В качестве общего требования — как можно больше кастомизации (я люблю все под себя настроить).
Как это ни странно прозвучит, но я считаю редактор ресурсов абсолютно не нужным компонентом IDE, в качестве внешнего приложения — сколько угодно. Не стоит изобретать велосипед.
3. Некоторые примеры IDE
После беглого осмотра я остановился на нескольких продуктах, претендующим на место на моем жестком диске в качестве среды, в которой мне было бы удобно творить. Именно творить, а не набивать текст и больше работать мышкой, прокручивая десятки килобайт листинга.
Итак, к своему неудовольствию, программы, полностью удовлетворяющей вышеперечисленным требованиям я не нашел. Собственно, этого я и ожидал, но все же некоторые продукты очень даже достойны внимания.
1. RadASM. Автор — Ketil Olsen. На этот продукт стоит однозначно обратить свое внимание, т.к. он сделан программистом на ассемблере для программистов на ассемблере. Кроме того, сам проект полностью написан на ассемблере. Один этот факт уже достоин уважения. Итак, мы имеем быстрый, маленький по объему и бесплатный IDE написанный энтузиастом для таких же энтузиастов. Среди возможностей — настраиваемая подсветка синтаксиса, автоподсказка при впечатывании функций WinApi, поддержка нескольких ассемблеров, плюс HLA, удобный выбор цветов и составление битовой маски, в панели свойств отображаются имена элементов языка с выпадающим списком либо аргументов (для процедур и макросов), либо элементов структуры (для структур соотв.), либо значений для констант. Есть возможность создавать ресурсы. Можно сворачивать процедуры и if-else a la MS Visual Studio .NET (collapsing). Есть интерфейс для плагинов. Вкратце — в нем есть все для работы со средними и малыми проектами. Почему он не пригоден для работы с большими? Допустим, у меня в проекте 300-400 процедур. Как мне в них ориентироваться, если нет абсолютно никакого поиска, простая сортировка по имени. Хорошо, хоть при впечатывании первых букв можно в выпадающем списке выбирать. При впечатывании имен структур и глобальных переменных меню с предложением вариантов возникает, только если нажать Ctrl-Space, а для этого я слишком ленив Локальные переменные и аргументы вообще не индексируются. Меню программы не продумано и неудобно (мне, например), для того, чтобы что-нибудь настроить, нужно хорошо полазить по меню. Нет возможности добавлять свои группы при подсветке синтаксиса.
2. Вторым пунктом хочу упомянуть небольшие, но (кажется?) развивающиеся проекты. Negatory Assembly Studio (www.negatory.com/asmstudio/) хочу упомянуть лишь как яркий пример того, что автор увлекся интерфейсом в ущерб функциональности. В результате получился симпатичный (хоть и спорный) интерфейс при практически полном отсутствии функциональности. По крайней я решил сохранить свое зрение, а не изучать функционал программы с жестко закодированным шрифтом размером в 6 pt. Еще одним продуктом, достойным упоминания (уже с лучшей стороны) является также индивидуальная разработка WinAsm (Antonis Kyprianou) (http://winasm.how.to/). Есть collapsing для процедур, при наборе понимает локальные переменные (после моей просьбы ) Выпадающий список из процедур все с тем же прокручиванием или поиском по первым буквам. Поддержка AddIn У этого проекта определенно есть перспективы, но и сейчас его можно использовать для небольших проектов.
Самое интересное я оставил на конец. Следующие 2 программы относятся к многофункциональным IDE, в которых можно разрабатывать не только программы на ассмеблере (точнее — не столько). Это — дорогие коммерческие приложения, (в отличие от первых — бесплатных) и серьезные игроки — по функциональным возможностям они не хуже (а иногда и лучше чем Visual Studio от Microsoft). Начнем с самого дорогого.
3. Visual SlickEdit. (www.slickedit.com) Цена — $269. И по размеру, и по спартанскому в общем интерфейсу (ну, по сравнению с VS, например) сразу видно, что продукт очень серьезный. И после продолжительного тестирования я все больше и больше убеждался в этом. Вначале вкратце о пакете вообще — одним словом — предназначен для программиста, причем неважно на каком языке писать, SlickEdit имеет поддержку таких языков, о которых я даже и не слышал . К своему немалому удивлению и радости ассемблер оказался в их числе, но об этом попозже. Пакет содержит мощный макроязык, синтаксически напоминающий С, с большим количеством примеров. Есть средство для сравнения файлов, причем все это с подсветкой и возможностью редактирования сравниваемых файлов. Для всех языков есть поддержка соответствующего синтаксиса, настраивается абсолютно все, что можно себе представить (и чего нельзя — тоже).
Имеется поддержка нескольких систем контроля версий (включая CVS). Возможностей пакета вполне хватает для конкуренции на равных с VS, а по некоторым параметрам — и превосходить. Что же мы имеем для работы с ассемблером? Легко настраивается подсветка синтаксиса, формата чисел. Возможность запуска внешних приложений с захватом и очень быстрым парсингом вывода — компилятора, например. При этом в случае ошибки к ней можно добраться одним щелчком. Есть поиск и замена. Для проекта на ассемблере есть дерево процедур в стиле MS VS, высвечиваются также глобальные переменные, макросы и структуры, правда, элементы структуры выводятся рядом, как независимые переменные (хотя для структур на C collapsing работает), и как это настроить для ассемблера, я так и не понял (возможно, скрипт переделывать).
4. Итак, последним по списку, но не по значению у меня Source Insight 3.5 (Source Dynamics, Inc.) Сайт — www.sourceinsight.com (Цена — $269).

При размере, на порядок меньшем (как у дистрибутива, так и в установленном виде), чем у SlickEdit функциональность не меньше, а порой и больше, чем у последнего. Хорошая настраиваемость, есть бейсикоподобный макроязык, но нет средств для коллективной работы (хотя я особо не искал). Интерфейс несколько отличается как от остальных, рассмотренных выше IDE, так и от VS. Что мне очень понравилось, так это то, что я могу видеть все процедуры, макросы, etc. как всего проекта, так и каждого файла по отдельности, плюс настроить, что именно я хочу видеть в данный момент — процедуры или константы, и т.д. Очень удобно сделан поиск по части названия (процедуры, например), а не по первым буквам.
Еще понравилась одна вещь, которой нет ни в одном IDE — Source Insight индексирует все мои структурные элементы программы и при наведении на них курсора, показывается нужный кусок кода внизу на панели. Для этой панели можно также задать ее размер и св-ва шрифта, но подсветка синтаксиса сохранится!

О подсветке синтаксиса тоже спою дифирамб — так, как ее можно настроить в Source Insight, я больше нигде не увидел в других продуктах. Очень удобно настраивается навигация по коду — я легко настроил ее как в броузере. Можно вывести статистику об используемых структурных элементах — об их встречаемости в проекте. Есть возможность вывести Relationship для процедур (надо сказать что для ассемблера эта функция работает, но несколько странновато результаты показаны). Для настройки парсинга локальных переменных пришлось написать регулярное выражение, правда, при этом включаются все локальные переменные файла, а не процедуры — не очень удобно, но терпимо. Зато при наборе любого текста появляется всплывающее меню autocompletion, при этом я могу пробежаться по предложенному списку, а все то же окошко внизу мне показывает первый десяток строк процедуры, например. Во время работы делается backup проекта, так что я практически застрахован от всяких неожиданностей, при аварийном завершении мне будет предложено восстановить работу на том месте, где ее прервал сбой. Кнопки сборки и запуска проекта идентичны кнопкам в VS. Из минусов, хоть и не критичных — долгий парсинг вывода, но зато я опять же могу не переходя сразу к коду, просмотреть первые строчки, при парсинге сразу же идет переход к первой ошибке (если они есть). Еще одна приятная мелочь — при печатании выражения, в котором есть несколько вложенных скобок, внешние становятся больше внутренних и сразу видна вложенность (хотя для ассемблера это не часто встречается). Еще одна немаловажная особенность, которой я больше нигде не видел, это подсвечивание строк, в которых произошли изменения — т.е. сразу можно увидеть, что и где я за этот сеанс изменил. Фактически, мне Source Insight напомнил улучшенный вариант VS + Visual Assist, и пока я свой выбор остановил на этом продукте.
4. Заключение
Данная статья отнюдь не претендует ни на полноту описания программ (это объем хорошей книги), ни на объективность, так как это только мое личное мнение. Нынешним и будущим авторам IDE также не стоит воспринимать все вышесказанное, как инструкцию о том, каким должно быть IDE, потому что я, например, после знакомства с Source Insight и не подозревал, как могут пригодиться те, казалось бы, мелочи, которые там есть.
В заключение скажу, что хотя Source Insight меня устраивает больше всего, окончательный выбор я еще не сделал, и верю, что возможно лучшее решение. © masquer
Где писать на ассемблере
Наиболее популярным инструментом для компиляции кода ассемблера для arm представляет компилятор GAS от проекта GNU, который входит в состав комплекта инструментов для разработки под ARM — Arm GNU Toolchain . Итак, вначале установим данный набор инструментов. Для этого перейдем на официальный сайт компании Arm на страницу https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads. Здесь представлены поседние версии Arm GNU Toolchain для разных архитектур.

Каждая версия Arm GNU Toolchain привязана к определенной версии компиляторов GCC. Например, версия Arm GNU Toolchain 12.2.Rel1 привязан к версии 12.2 набора компиляторов gcc.
Для ОС Windows доступно несколько групп пакетов по различные архитектуры:
AArch32 bare-metal target (arm-none-eabi) : для компиляции программ под 32-битные архитектуры без привязки к конкретной операционной системе
AArch32 GNU/Linux target with hard float (arm-none-linux-gnueabihf) : для компиляции программ под 32-битную ОС Linux
AArch64 bare-metal target (aarch64-none-elf) : для компиляции программ под 64-битные архитектуры без привязки к конкретной операционной системе
AArch64 GNU/Linux target (aarch64-none-linux-gnu) : для компиляции программ под 64-битную ОС Linux
Как видно из названия, наборы компиляторов имеют названия типа arm-none-linux-gnueabi , arm-none-eabi , arm-eabi и т.д. Все эти названия формируются по шаблону
arch : указывает на архитектуру
vendor : указывает на производителя
os : указывает на целевую операционную систему
eabi : сокращение от Embedded Application Binary Interface
Например, пакет инструментов arm-none-eabi предназначен для 32-х битной архитектуры, не зависит от конкретного вендора, операционной системы и компилируется с помощью ARM EABI.
Другой пример: пакет инструментов arm-none-linux-gnueabi предназначен для 32-х битной архитектуры, но создает бинарники непосредственно для ОС Linux и использует GNU EABI.
Поскольку в данном случае в данном случае мы рассматриваем именно arm64, то нас будет интересовать прежде всего те пакеты, которые начинаются на AArch64 . И поскольку пакет AArch64 bare-metal target (aarch64-none-elf) не привязан к определенной ОС, то выберем его. Кроме того, он доступен для всех основных ОС. Однако отмечу, что, если планируется писать код именно под Linux (в том числе Android), то лучше использовать AArch64 GNU/Linux target (aarch64-none-linux-gnu) — он создает более компактные (иногда намного меньшие) исполняемые файлы.
Для Windows доступны пакеты в двух вариантах: установочный файл exe , который устанавливает все необходимые файлы в папку C:\Program Files (x86) , и zip -архив — по сути те же самые файлы, которые мы можем распаковать в любое нужное для нас расположение. Большой разницы между файлами из exe и zip нет, но для простоты выберем exe-файл (в моем случае это файл arm-gnu-toolchain-12.2.rel1-mingw-w64-i686-aarch64-none-elf.exe

После загрузки запустим установщик

Прощелкаем по шагам и в конце на последнем окне после установки установим флажок Add path to environment variable , чтобы добавить путь к компилятору и другим инструментам в переменные среды:

Если мы посмотрим на добавленный в переменные среды путь (в данном случае каталог C:\Program Files (x86)\Arm GNU Toolchain aarch64-none-elf\12.2 rel1\bin ), то мы найдем файлы компилятора и ряд других файлов:

В этом комплекте нам понадобится прежде всего сам ассемблер — файл aarch64-none-elf-as.exe , который по коду ассемблера Arm64 создает объектный файл. Кроме того, также потребуется файл aarch64-none-elf-as.ld , который также располагается в этой папке и который генерирует из объектного файла исполныемый файл.
Для проверки настройки откроем терминал/командную строку и выведем версию компилятора следующей командой:
Мы должны получить вывод типа следующего:
Создание первой программы
Теперь напишем первую простейшую программу, которая просто будет выводить на консоль некоторую строку. Для этого создадим на жестком диске какой-нибудь каталог, например, C:\arm . Создадим в этого каталоге новый файл hello.s (обычно файлы с кодом ассемблера arm имеют расширение .s ). Определим в этом файл следующий код:
Для большего понимания я снабдил программу комментариями. GNU Assembler использует тот же самый синтаксис комментариев, что и C/C++ и другие си-подобные языки: одиночный комментарий начинается с двойного слеша // . Также можно использовать многострочный комментарий с помощью символов /∗ и ∗/ , между которыми помещается текст комментария ( /* текст комментария */
Вначале надо указать линкеру (в нашем случае программа ld) стартовую точку программы. В данной программе стартовая точка программы проецируется на метку _start . И чтобы линкер получил к ней доступ, определяет _start в качестве глобальной переменной с помощью оператора global .
Одна программа может состоять из множества файлов, но только один из них может иметь точку входа в программу _start
Далее идут собственно действия программы. Вначале вызывается инструкция mov , которая помещает данные в регистр.
Значения X0-X2 представляют регистры для параметров функции в Linux. В данном случае помещаем в регистр X0 значение «#1». Операнды начинаются со знака «#» Число 1 представляет номер стандартного потока вывода «StdOut», в данном случае, грубо говоря, вывод на консоль.
Далее загружаем в регистр X1 адрес строки для вывода на экран с помощью инструкции ldr
Затем также с помощью инструкции mov помещаем в регистр X2 длину выводимой строки
Для любого системного вызова в Linux параметры помещаются в регистры X0–X7 в зависимости от количества. Затем в регистр X0 помещается код возврата. А сам системный вызов определяется номером функции из регистра X8. Здесь помещаем в X8 функцию с номеро 64 (функция write )
Далее выполняем системный вызов с помощью оператора svc
Операционная система, используя параметры в регистрах и номер функции, выведет строку на экран.
После этого нам надо выйти из программы. Для этого помещаем в регистр X0 число 0
А в регистр X8 передаем число 93 — номер функции для выхода из программы (функция exit )
И с помощью svc также выполняем функции. После этого программа должна завершить выполнение.
В самом конце программы размещена секция данных
Оператор .data указывает, что дальше идет секция данных. Выражение .ascii выделяет память и помещает в нее указанную далее строку.
Строка завершается символом перевода строки «\n», чтобы не надо было нажимать на Return, чтобы увидеть текст в окне терминала.
Компиляция приложения
Для компиляции приложения откроем терминал/командную строку и командой cd перейдем к папке, где расположен файл hello.s с исходным кодом программы. И для компиляции выполним команду:
Компилятору aarch64-none-elf-as в качестве параметра передается файл с исходным кодом hello.s. А параметр -o указывает, в какой файл будет компилироваться программа — в данном случае в файл hello.o. Соответственно в папке программы появится файл hello.o
Затем нам нужно скомпновать программу с исполняемый файл с помощью линкера aarch64-none-elf-ld командой:
После этого в папке программы появится исполняемый файл hello, который мы можем запускать на устройстве с архитектурой ARM под управлением Linux.

Тестирование приложения на Android
Итак, у нас есть исполняемый файл программы. Мы ее можем протестировать. Для этого нам нужен Linux на устройстве с архитектурой ARM. В качестве такого устройства я возьму самый распространенный вариант — смартфон под управлением Android. Поскольку Android построен на базе Linux и как правило устанавливается на устройства с arm архитектурой.
Для установки файла на Android нам понадобится консольная утилита adb , которая устанавливается в рамках Android SDK. Android SDK обычно устанавливается вместе с Android Studio. Но если Android Studio не установлена, то можно загрузить пакет https://dl.google.com/android/repository/platform-tools-latest-windows.zip. В составе этого пакета или в составе SDK в папке platforms-tools можно найти нужную нам утилиту adb .

Для упрощения работы путь к этой утилите лучше добавить в переменные среды, чтобы не прописывать к ней полный путь.
Теперь переместим скомпилированный файл hello на устройство под Android. Для этого подключим через usb к компьютеру смарфтон с Android и перейдем в консоли с помощью команды cd к папке с файлом hello используем следующую команду
То есть в данном случае используем команду push для помещения копии файла hello на смартфон в папку /data/local/tmp/