На чем написан ассемблер
Перейти к содержимому

На чем написан ассемблер

  • автор:

Ассемблер

Ассемблер или asm (англ. assembler — сборщик) — утилита, транслирующая исходники программы на языке ассемблера собственно в машинный код, то есть на язык бездушной машины. Для обратного превращения существует дизассемблер (англ. disassembler — разборщик, ломалка), широко используемый хакерами. Но это для шибко грамотных, а все остальные словом «ассемблер» называют сам язык ассемблера — простейший способ записи машинного кода с помощью расовых английских сокращений, называемых мнемониками (см. в конце статьи — если осилите). Поскольку язык ассемблера привязан к устройству процессора, программы на нем не являются переносимыми на иную компьютерную архитектуру, так как тип процессора жёстко определяет набор доступных команд машинного языка. Но это не так уж и важно, так как нет процессора кроме x86 и фон Нейман пророк его, а всякие Жабы и дотнеты вообще используют собственные виртуальные машины с собственным асмом — похуй, что в тысячу раз медленнее, зато переносимость и безопасность, блджад!

Содержание

История [ править ]

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

Простейший транслятор (ассемблер первого поколения) позволял фактически просто писать машинные команды на «человеческом» языке, что позволило программерам немного расслабиться. Достаточно быстро туда добавились многочисленные свистелки и перделки, нарушающие Истинную Красоту Программирования На Ассемблере, но еще больше экономящие время и силы (а значит и деньги), как то макросы, библиотеки и прочее. Затем появились языки высокого уровня и компиляторы (более интеллектуальные генераторы кода с более понятного человеку языка) и интерпретаторы (исполнители человекописанной программы на лету). Которые совершенствовались, совершенствовались, совершенствовались, и досовершенствовались до «программирования мышкой», а компиляторы научились генерировать код, которому по скорости написанный человеком начал сливать [1] . Такие дела.

В целом история языков программирования протекает в направлении от программирования на языке компьютера до манипуляции абстракциями вроде Послать.Лесом(всех(кому не нравится эта статья)) Ну или (послать (лесом (всех (кому-не-нравится «эта-статья»)))) или

На языке ассемблера этот код занял бы более 9000 строк. И потребовал бы долгой и кропотливой работы по своему созданию. Зато, в отличие от Шindoшs, оно бы работало, а не только свистело, пердело, выдавало красивые иконки и жрало 640K памяти.

Асмофлаги и студенты из Политеха [ править ]

Среди программистов с длинной бородой, видевших еще те компьютеры-динозавры, есть такие, которые очень трепетно относятся к напейсанию кода, и считают, что ассемблер — это труЪ, а языки высокого уровня — шлак и унылое говно, предназначенные исключительно для быдлокодерства. При упоминании факта, что современные компиляторы генерируют гораздо более быстрый код, начинают срать кирпичами и обзываться нехорошими словами, ибо сама мысль, что машина может быть умнее человека, считается недопустимой и кощунственной. При этом упускается тот факт, что компиляторы, вообще-то, пишут люди. Степень владения языком ассемблера считается мерилом отличия программиста от быдлокодера. Наиболее тяжелый клинический случай представляет молочный брат Линуса расовый чухонец Вилле Турьянмаа, написавший целую ОС — MenuetOS на чистом ассемблере. На ассемблере же была написана первая версия UNIX, коя им и не является по нынешним понятиям, так как позже была переписана чуть более, чем наполовину на C и помещена в анналы истории.

Тем не менее, программирование на языке ассемблера очень часто используется при написании программ, использующих возможности процессора, не реализуемые языками высокого уровня, а также программировании всевозможных нестандартных программистских хитростей. Драйвера для новых устройств тоже содержат в себе чуть менее, чем половину ассемблерного кода, коий при доведении их до ума ушастыми мартышками заменяют на стандартный C/C++. Часто компиляторы (чуть менее, чем все) предоставляют возможность вставлять ассемблерный код в текст программы.

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

Понятно, что писать что-либо крупное на ассемблере в современном мире не будет даже самый отъявленный маньяк, даже большинство фирмваря и прочих глюкалок для микроконтроллеров сейчас пишется на чем-то более продвинутом. Но когда стоимость каждого лишнего не то что мегабайта, а полубайта в ОЗУ становится критичной (ибо их просто нет, например на каком-нибудь запущенном много лет назад спутнике, до которого можно достучаться по радио, но никак физически), выливаются в миллиарды и даже жизни (встроенный софт бортовых систем в авиации и космонавтике) — ассемблер strikes back! К примеру, софт для кораблей «Союз ТМА-М», «Прогресс М-М» написан на Си (по крайней мере, российский сегмент МКС). ПО ЦВМов «Бурана» писалось на ПРОЛ-2. «Союз ТМА» — не на Си, у него БЦВК «Аргон-16», сначала программировали его на ассемблере, в поздних машинах транслировали на высокоуровневый язык. Спутники «Ямал» и «Белка» написаны на Си.

Ассемблер и ЛинуксGt [ править ]

Хотя программирование на ассемблере в Unix-мире считается моветоном, поскольку нарушает один из основополагающих принципов unix way «жертвуй производительностью ради переносимости», даже тут находится место разногласиям, способным вылиться в настоящую драму.

Дело в том, что встроенный ассемблер большинства Unix-ов (и Linux в том числе) использует синтаксис (AT&T-синтаксис), в корне отличающийся от оригинального Intel-синтаксиса. А поскольку Intel-синтаксис у большинства труЪ-линуксоидов прочно ассоциируется с маздаем, он объявляется ересью, и всем, кто пользуется nasm, yasm или fasm пророчатся вечные муки, страшный суд, ад и погибель, хотя gas тоже владеет интеловским синтаксисом. Правда все ELF-инфекторы всё же приходится писать на старом добром асме.

Алсо какой либо годной документации по ассемблеру AT&T в интернете хрен найдешь. По этой причине программистов на AT&T крайне мало. А по этой причине некому писать документацию.

Ассемблер в кино [ править ]

Как минимум один раз снялся в кино, но зато в каком! В первой части Терминатора можно видеть как Киборгъ предпочитает MOS Technology 6510/8500 ассемблер.

Необходимое пояснение. На скриншоте видна программка из чередующихся инструкций LDA-STA-LDA-STA…(load-store-load-store). В семействе 6502 программы состоят чуть менее, чем полностью из LDA/LDY/LDX/STA/STX/STY вследствие наличия всего 3х 8-битных регистров. Наличие почти полного отсутствия регистров компенсируется нулевой страницей памяти, откуда-куда постоянно приходится перекладывать байтики, так как хранить их более негде. В данном ЦПУ 13 режимов адресации на всего 53 команды. Алсо порты ввода-вывода замаплены в адреса памяти, так что чтение-запись из-в порты осуществляется также этими командами. Короче: программы в Терминаторе имеют вполне осмысленный вид и не являются кучей команд от балды. Подробнее: Этот удивительный Терминатор /48076 .

Во второй части интерфейс Терминатора более очеловечен. Впрочем, это можно объяснить тем, что ПО для первого терминатора делал Скайнет, а для второго набыдлокодил Джон Коннор.

Алсо, ассемблер семейства 8080 (у нас серия КР580) засветился в давнем аниме «Megazone 23».

Область применения [ править ]

  • Популярен для допиливания зацикливаемых кусков программы… в роли напильника. Перепиливание критических участков кода может принести PROFIT, а может и не принести. В любом случае, заниматься таким перепиливанием стоит только тогда, когда у вас на руках уже полностью работающий алгоритм, который можно было бы ускорить, а не наоборот.
  • Для использования в софтине новых команд, доступных в новых процессорах. Компилятор хоть и оптимизирует код высокого уровня при компиляции, но… практически никогда не способен генерировать инструкции из расширенных наборов команд типа AVX, СTV, XOP и т. п. Потому что команды в процессоры добавляют быстрее, чем в компиляторах появляется логика для генерации этих команд.
  • Используется для написания кода, создание которого невозможно (или затруднено) на языках высокого уровня, например, получение дампа памяти/стека. Даже когда аналог на языке высокого уровня возможен, профит от языка ассемблера может быть значительным в разы. Например, реализация подсчета среднего суммы двух чисел с учётом переполнения для x86 процессоров занимает всего 2 команды (сложение с выставлением флага переноса и сдвиг с заёмом этого флага). Аналог на языке высокого уровня ((long) x + y) >> 1
    1. может не работать в принципе, ведь sizeof(long) == sizeof(int). Ну или может бомбануть, как это было на ракете Ариан-5 (64-ичные переменные с плавающей запятой float преобразовывались в 16 бит фиксированных, когда программа дошла до 32767+1, у ракеты включилась система «самоуничтожение на случай попадания в мир КГБ» прямо на космодроме.
    2. при компиляции конвертируется в чуть менее чем дохрена команд процессора.

Ещё пример: перемножение чисел с фиксированной запятой в языке, в который не вшита поддержка такого формата чисел. На ассемблере это умножение eax на edx с сохранением 64-битного результата в edx:eax с последующим сдвигом вправо (shrd). На ЯВУ это выглядит либо как (x*y)>>16, что не даёт верный результат при выходе результата умножения за 32 бита, либо как (int64(x)*y)>>16, что конвертируется в дохрена команд. Впрочем, в данных примерах современные компиляторы умеют правильно понимать намерения программиста и генерировать оптимальный код.

  • Также может использоваться задротами для написания очень компактных программ. Пример: клиент для аськи, занимающий в скомпилированном виде 34 КБ. Другой пример: тоже IM-клиент Faim 0.21 — 12.61 КБ. Отдельная дисциплина этой специальной олимпиады — демки.
  • В вузах изучается для вливания в МНУ студентоты познаний об устройстве и работе компьютера на уровне повыше кликанья мышкой по окошкам. Отличное лекарство от быдлокодерства (ну, а для оказавшихся неспособными осилить, соответственно — окончательное решение).
  • Является единственным языком программирования для создания достойных инфекторов — Cih, Sality, Sinowal.
  • Чуть более чем половина программ для GPU пишутся на ассемблере, наряду с использованием языков высокого уровня HLSL или GLSL . Хороший, годный шейдер обязательно содержит асму, ибо GPU — это принципиально узкое место для выделения графической составляющей в монитор (Есть, конечно и более современные методы типа использования OpenCL, но всё же ASM << C).
  • Оптимизация невъебенно затратных математических алгоритмов. Часто встречается в исходниках фильтров для так любимого видеопиратами и аниматорами винрарнейшего AviSynth.
  • Промежуточный этап между неким левым синтаксисом (не обязательно даже языком, это может быть визуальный «конструктор» программы вроде ДРАКОНа) и исполнимым кодом. Петя хочет анализ Фурье на ЦСП на участке в миллисекунду, а Вася в две? Нет проблем, нажимайте кнопочки и собирайте в проект полученные пятидесятиметровые ассемблерные сырцы, работающие с предельно возможной именно для конкретного случая скоростью. Не компилятор же отдельный писать ради Васи и Пети, честное слово.
  • Программирование под устаревшие платформы (NES, например), которым мешает использовать «сбалансированный» Си крайне низкая производительность и нужда в хитрых изъёбах при обработке данных и графики.
    Тамошний ассемблер, в отличие от этих ваших x86, обладает Духовностью и Минимализмом.

Пример программирования [ править ]

Нижеследующий кусок кода переключает процессор из реального (16-битного) режима в длинный (64-битный). Эпичность заключается в «прыжке через десятилетия», поскольку переключает ЦП x86 из режима совместимости со своим предком 1979 года рождения, в коем он находится сразу после подачи питания, в современный (2003 года разработки), где доступны все инструкции и всё адресное пространство памяти.

Данный пример написан для ассемблера nasm:

Вообще, в среде ASM программистов существует целая война ассемблеров. Кто-то предпочитает nasm (распространяется нахаляву, из-за этого и приобрёл популярность у некоторых кодеров), кто-то tasm, masm или fasm. На самом деле вроде бы и ерундовая вещь, но каждый ассемблер имеет ряд ограничений, и в то же время некоторые другие особенные фичи. Поэтому не удивляйтесь, если кто-то будет с пеной у рта отстаивать свой ассемблер, или тому, что код, написанный под одну разновидность, на другой попросту не оттранслируется. Ассемблер имеет множество диалектов, некоторые из них довольно продвинуты, к примеру макросы fasm чем-то напоминают язык высокого уровня, поэтому он вызывает в среде ассемблерщиков некоторый баттхёрт, да ещё и ассоциации с хорошо оптимизированным и разбитым на отдельные операции с прямыми указателями Си делают контрольный выстрел.

Мнение изучающей студентоты [ править ]

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

Мнение изучившей студентоты [ править ]

Будучи изученным в течение нескольких лет в вузе и применяемым на практике, добавляет стопицот к ЧСВ, что мешает при необходимости программировать на не-ТруЪ-языках при смене работы (а также пола, возраста, профессии и т.п). Например, писать на javascript после ассемблера походит на процесс создания красных сердечек на торте из сахара паяльником: дорого, долго и болезненно. Зато чем-то похоже на ТруЪ

Как писать на ассемблере в 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

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

Advanced

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

4. Практика

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

  • MASM64 простое окно masm64SimpleWindow.asm
  • FASM64 простое окно fasm64SimpleWindow.asm

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

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

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

Что такое ассемблер для чайников

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

1. Что такое ассемблер?

Начнем с основ и разберемся с уровнями языков. Все языки программирования, а их в настоящее время создано довольно много, делятся на высокоуровневые и низкоуровневые. К первой категории относятся удобочитаемые, проблемно-ориентированные языки — простые для понимания людьми (как английский или русский).

На них легко разрабатывать и поддерживать любые приложения, сервисы, функционал для решения отдельных задач и т.д. К этой категории относятся большинство созданных ныне языков, например: C, Python, Pascal, Basic и другие.

Языки программирования низкого уровня делятся на две категории:

Это единственный язык, воспринимаемый компьютером. Записывается он при помощи двоичной системы исчисления, в виде строк из единиц (1) и нулей (0). Когда такая последовательность цифр передается машине, она преобразует их в электрические сигналы, необходимые для ее запуска. Выглядит это так:

Его нелегко понять человеку , но он крайне информативен для машины.

Программы, написанные на таком языке выполняются компьютером очень быстро. Ведь инструкции идут напрямую в ЦП, и перевод программы не требуется. Но недостатки такого кода перевешивают его преимущества:

  • Зависимость от машины. Поскольку внутреннее устройство компьютеров может отличаться — программа, написанная на одной машине, может не подойти для другой.
  • Сложность программы. Программист, работающий на машинном языке, должен хорошо знать аппаратную структуру компьютера.
  • Увеличивается риск возникновения ошибок.
  • Крайне трудно, а порой и невозможно редактировать код.

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

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

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

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

Языки ассемблера имеют следующие преимущества перед машинными языками:

  1. Легче понять и использовать. Вместо числовых кодов — используются мнемоники — зарезервированные короткие слова, используемые для каждой низкоуровневой инструкции (например, Mov указывает на перемещение информации из одного места в другое, а Add применяется для добавления данных в определенную ячейку).
  2. Легко найти и исправить ошибки.
  3. Легче редактировать.

Но недостатки все же тоже имеются:

    Зависимость от машины. Программы, написанные на языке ассемблера, разработаны для конкретной марки и модели используемого процессора и поэтому зависят от машины.

2. Ассемблер и работа процессора

Ассемблер был создан в 1947 году Кэтлин Бут — британско-канадским ученым и инженером, первопроходцем в области информатики. Но по достоинству его оценили только в начале 70-х годов, когда он стал применяться в электронных калькуляторах с памятью, новшеством того времени. Сейчас без него не обойтись в программировании процессоров вычислительных машин.

Чтобы выяснить принцип работы ассемблера, проясним некоторые нюансы внутреннего устройства процессора.

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

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

  • Регистры общего назначения. Их всего восемь и каждый из них хранит 4 байта каких-нибудь данных.
  • Указатели команд. Регистры, хранящие в себе адрес каждой последующей команды, выполняемой процессором.
  • Регистр флагов. Флаг — некое свойство процессора, применяемое для обозначения кода, в случаях когда его нужно пометить.
  • Сегментные регистры нужны для работы с оперативной памятью.

Подводя предварительный итог, стоит отметить, что все с чем работает ассемблер, — это команды процессора, переменные и регистры.

3. Команды ассемблера

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

Кратко разберем синтаксис рассматриваемого языка и выясним, как на нем выглядит любая из команд:

Метка — это, своего рода, название для определенного фрагмента кода.

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

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

Все это нужно для упрощения понимания ассемблера: для того, чтобы его команды хотя бы отдаленно напоминали человеческий язык.

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

Операндами могут стать имя регистра, любая ячейка памяти или служебная часть команды.

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

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

<strong>mov al, x</strong> ; Пересылаем x в регистр AL

<strong>imul al</strong> ; Умножаем регистр AL на себя, AX = x * x

<strong>movsx bx, x</strong> ; Пересылаем x в регистр BX со знаковым расширением

<strong>imul bx</strong> ; Умножаем AX на BX. Результат разместится в DX:AX

4. Какие программы нельзя написать на ассемблере?

Если подумать, то таковых нет. Все, что возмож­но сотворить на ПК, мож­но создать и на ассем­бле­ре. Ведь ассем­блер — это ничто иное, как тек­сто­вое обозначение необработанного машин­ного языка, в который компилируются абсолютно все приложения, которые можно запустить на компь­юте­ре.

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

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

Итак, да, на ассемблере можно теоретически написать все — но целесообразно ли это?

5. Почему это круто?

Итак, для чего вам может понадобиться знания ассем­блера:

  1. Чтобы выяснить внутреннее устройство всех компь­ютер­ных прог­рамм в деталях, до самого низкого уровня.
  2. Чтобы научиться делать прог­раммы для мик­рокон­трол­леров и адаптеров устройств.
  3. Чтобы по­нять принципы создания и работу язы­ков высоко­го уров­ня.
  4. Для создания своего собс­твен­ного ком­пилятора, опти­миза­тора, вир­туаль­ной машины, драйвера и т.д.
  5. Для взло­ма, отла­дки или защиты компьютерных сис­тем на самом низ­ком уров­не, ведь большинство изъ­янов безопас­ности можно проанализировать и найти толь­ко на уров­не машин­ного кода.

Также используя ассемблер можно работать с ЦП и с памятью напрямую — при этом скорость обработки данных крайне высокая. Это потому, что процессорное время излишне не расходуется. В процессоре, работающем на частоте 3 гГц — ассемблером будет выполняться примерно 2,5 миллиарда команд в секунду. Это в тысячу раз больше, чем на том же Python и Javascript.

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

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

6. Почему это сложно?

Чтобы кодить на ассемблере, нужно питаться железными бобами, иметь гранитное терпение, а еще:

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

А еще забудьте про привычные готовые библиотеки кода и наличие адекватных читабельных конструкций.

7. Тогда для чего он нужен?

Ассемблер необходим при разработке следующих вещей:

  • драйверов;
  • при программировании микроконтроллеров и процессоров;
  • для быстрой разработки кусков операционных систем;
  • антивирусов или вирусов.

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

8. Стоит ли начинать изучать программирование с ассемблера в 2022 году?

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

Хо­рошие прог­раммис­ты зна­ют ассем­блер, но поч­ти никог­да не пишут на нем.

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

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

Конечно, в какой‑то момент, вам все равно придется с ним оз­накомить­ся, осо­бен­но при прог­рамми­ровании на Си, но начинать с ассем­бле­ра не сто­ит.

9. Насколько легче учить другие языки, когда уже знаешь ассемблер?

Язык ас­сем­блера абсолютно не похож на высокоуровневые язы­ки. Поэтому, расхожее мнение о том, что если знаешь один язык программирования, второй выучить очень легко — тут не работа­ет. Вывод: после изучения ассем­бле­ра, другие языки при­дет­ся осваивать почти с нуля.

Чем же он так отличается от других? Ну во-первых, перемен­ная тут— это прос­то определенная область памяти. Нет распространенных типов данных вроде int или char , нет мас­сивов, нет циклов, нет функций! Есть толь­ко память. При­чем, даже если ты чего-то сделаешь не так — прог­рамма скорее всего ском­пилиру­ется, но обру­шит­ся в ран­тай­ме, без каких-либо сооб­щений об ошиб­ке.

Поэтому начинать луч­ше с высокого уровня, например с Си. Изучив его, вам уже лег­че перенести свои знания на любой дру­гой язык, будь то Java, Python или какой‑то еще, да и с ассем­бле­ром лег­че разоб­рать­ся.

10. Востребованы ли специалисты по программированию на ассемблере?

Заглянув на популярные сайты по поиску работы, вам очень сильно повезет, если вы найдете хотя бы одну вакансию, в заголов­ке которой прописа­но сло­во «ассем­блер». И это действительно так.

Крайне редко может появиться позиция, где одна из компаний будет искать волшебника 99 уровня, хорошо знающего внутренний мир компь­юте­ров, уме­ющего латать сис­тему без исходно­го кода, способного пол­ностью под­чинить себе любую операционку. Но это скорее исключение из правил.

Пот­ребности в такой магии, на сегодняшний день — практически нет.

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

Надеюсь, наша вводная статья была для вас полезна. Чтобы более детально начать изучать рассматриваемую нами тему, делимся ссылками на актуальные видеоролики по работе с ассемблером:

Язык ассемблера

Язык ассе́мблера (англ.  assembly language ) — машинно-ориентированный язык низкого уровня с командами, обычно соответствующими командам машины, который может обеспечить дополнительные возможности вроде макрокоманд [1] ; автокод, расширенный конструкциями языков программирования высокого уровня, такими как выражения, макрокоманды, средства обеспечения модульности программ [2] . Автокод — язык программирования, предложения которого по своей структуре в основном подобны командам и обрабатываемым данным конкретного машинного языка. [2]

Язык ассемблера — система обозначений, используемая для представления в удобочитаемой форме программ, записанных в машинном коде. Язык ассемблера позволяет программисту пользоваться алфавитными мнемоническими кодами операций, по своему усмотрению присваивать символические имена регистрам ЭВМ и памяти, а также задавать удобные для себя схемы адресации (например, индексную или косвенную). Кроме того, он позволяет использовать различные системы счисления (например, десятичную или шестнадцатеричную) для представления числовых констант и даёт возможность помечать строки программы метками с символическими именами с тем, чтобы к ним можно было обращаться (по именам, а не по адресам) из других частей программы (например, для передачи управления). [3]

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

Содержание

Содержание языка

Команды языка ассемблера один к одному соответствуют командам процессора. Фактически, они и представляют собой более удобную для человека символьную форму записи — мнемокоды — команд и их аргументов. При этом одной команде языка ассемблера может соответствовать несколько вариантов команд процессора. [4]

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

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

Каждая модель (или семейство) процессоров имеет свой набор — систему — команд и соответствующий ему язык ассемблера. Наиболее популярные синтаксисы языков ассемблера — Intel-синтаксис и AT&T-синтаксис.

Существуют компьютеры, реализующие в качестве машинного язык программирования высокого уровня (Форт, Лисп, Эль-76). Фактически, в таких компьютерах они выполняют роль языков ассемблера.

Достоинства и недостатки

Достоинства

  • Язык ассемблера позволяет писать самый быстрый и компактный код, какой вообще возможен для данного процессора.
  • Если код программы достаточно большой, — данные, которыми он оперирует, не помещаются целиком в регистрах процессора, то есть частично или полностью находятся в оперативной памяти, — то искусный программист, как правило, способен значительно оптимизировать программу по сравнению с транслятором с языка высокого уровня по одному или нескольким параметрам:
    • скорость работы — за счёт оптимизации вычислительного алгоритма и/или более рационального обращения к ОП, перераспределения данных;
    • объём кода (в том числе за счёт эффективного использования промежуточных результатов). (Сокращение объёма кода также нередко повышает скорость выполнения программы.)

    Недостатки

    • В силу машинной ориентации («низкого» уровня) языка ассемблера человеку сложнее читать и понимать программу на нём по сравнению с языками программирования высокого уровня; программа состоит из слишком «мелких» элементов — машинных команд, соответственно, усложняются программирование и отладка, растут трудоёмкость и вероятность внесения ошибок.
    • Требуется повышенная квалификация программиста для получения качественного кода: код, написанный средним программистом на языке ассемблера, обыкновенно оказывается не лучше или даже хуже кода, порождаемого оптимизирующим компилятором для сравнимых программ, написанных на языке высокого уровня. [5]
    • Программа на языке высокого уровня может быть перекомпилирована с автоматической оптимизацией под особенности новой целевой платформы [6] , программа же на языке ассемблера на новой платформе может потерять своё преимущество в скорости без ручного переписывания кода. [7][8]
    • Как правило, меньшее количество доступных библиотек по сравнению с современными индустриальными языками программирования.
    • Отсутствует переносимость программ на компьютеры с другой архитектурой и системой команд.

    Применение

    Исторически, если первым поколением языков программирования считать машинные коды, то язык ассемблера можно рассматривать как второе поколение языков программирования. Недостатки языка ассемблера, сложность разработки на нём больших программных комплексов привели к появлению языков третьего поколения — языков программирования высокого уровня (таких как Фортран, Лисп, Кобол, Паскаль, Си и др.). Именно языки программирования высокого уровня и их наследники в основном используются в настоящее время в индустрии информационных технологий. Однако языки ассемблера сохраняют свою нишу, обусловленную их уникальными преимуществами в части эффективности и возможности полного использования специфических средств конкретной платформы.

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

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

    С использованием программирования на языке ассемблера производятся:

    • Оптимизация критичных к скорости участков программ в программах на языках высокого уровня, таких как C++ или Pascal. Это особенно актуально для игровых приставок, имеющих фиксированную производительность, и для мультимедийныхкодеков, которые стремятся делать менее ресурсоёмкими и более быстрыми.
    • Создание операционных систем (ОС) или их компонентов. В настоящее время подавляющее большинство ОС пишут на более высокоуровневых языках (в основном на Си — языке высокого уровня, который специально был создан для написания одной из первых версий UNIX). Аппаратно зависимые участки кода, такие как загрузчик ОС, уровень абстрагирования от аппаратного обеспечения (hardware abstraction layer) и ядро, часто пишутся на языке ассемблера. Фактически, ассемблерного кода в ядрах Windows или Linux совсем немного, поскольку авторы стремятся обеспечить переносимость и надёжность, но, тем не менее, он там присутствует. Некоторые любительские ОС, такие как MenuetOS, целиком написаны на языке ассемблера. При этом MenuetOS помещается на дискету и содержит графический многооконный интерфейс.
    • Программирование микроконтроллеров (МК) и других встраиваемых процессоров. По мнению профессора Таненбаума, развитие МК повторяет историческое развитие компьютеров новейшего времени. [9] На сегодняшний день для программирования МК весьма часто применяют язык ассемблера (хотя и в этой области широкое распространение получают языки вроде Си). В МК приходится перемещать отдельные байты и биты между различными ячейками памяти. Программирование МК весьма важно, так как, по мнению Таненбаума, в автомобиле и квартире современного цивилизованного человека в среднем содержится 50 микроконтроллеров. [10]
    • Создание драйверов. Некоторые части драйверов программируют на языке ассемблера. Хотя в целом в настоящее время драйверы также стараются писать на языках высокого уровня в связи с повышенными требованиями к надёжности и достаточной производительностью современных процессоров и достаточным совершенством компиляторов с языков высокого уровня. Надёжность для драйверов играет особую роль, поскольку в Windows NT и UNIX (в том числе в Linux) драйверы работают в режиме ядра. Одна ошибка в драйвере может привести к краху всей системы.
    • Создание антивирусов и других защитных программ.
    • Написание трансляторов языков программирования.

    Связывание программ на разных языках

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

    • На этапе компиляции — вставка в исходный код программы на языке высокого уровня ассемблерных фрагментов (англ.  inline assembler ) с помощью специальных директив языка. Способ удобен для несложных преобразований данных, но полноценного ассемблерного кода, с данными и подпрограммами, включая подпрограммы со множеством входов и выходов, не поддерживаемых языком высокого уровня, с его помощью сделать невозможно.
    • На этапе компоновки при раздельной компиляции. Для взаимодействия компонуемых модулей достаточно, чтобы импортируемые функции (определённые в одних модулях и используемые в других) поддерживали определённое соглашения вызова (англ.  calling conventions ). Написаны же отдельные модули могут быть на любых языках, в том числе и на языке ассемблера.

    Синтаксис

    Синтаксис языка ассемблера определяется системой команд конкретного процессора.

    Набор команд

    Типичными командами языка ассемблера являются (большинство примеров даны для Intel-синтаксиса архитектуры x86):

    • Команды пересылки данных ( mov и др.)
    • Арифметические команды ( add , sub , imul и др.)
    • Логические и побитовые операции ( or , and , xor , shr и др.)
    • Команды управления ходом выполнения программы ( jmp , loop , ret и др.)
    • Команды вызова прерываний (иногда относят к командам управления): int
    • Команды ввода/вывода в порты ( in , out )
    • Для микроконтроллеров и микрокомпьютеров характерны также команды, выполняющие проверку и переход по условию, например:
    • cjne  — перейти, если не равно
    • djnz  — декрементировать, и если результат ненулевой, то перейти
    • cfsneq  — сравнить, и если не равно, пропустить следующую команду

    Инструкции

    Типичный формат записи команд:

    где мнемокод — непосредственно мнемоника инструкции процессору. К ней могут быть добавлены префиксы (повторения, изменения типа адресации и пр.).

    В качестве операндов могут выступать константы, адреса регистров, адреса в оперативной памяти и пр. Различия между синтаксисом Intel и AT&T касаются в основном порядка перечисления операндов и указания различных методов адресации.

    Используемые мнемоники обычно одинаковы для всех процессоров одной архитектуры или семейства архитектур (среди широко известных — мнемоники процессоров и контроллеров x86, ARM, SPARC, PowerPC, M68k). Они описываются в спецификации процессоров. Возможные исключения:

    • если ассемблер использует кроссплатформенный AT&T-синтаксис (оригинальные мнемоники приводятся к синтаксису AT&T);
    • если изначально существовало два стандарта записи мнемоник (система команд была наследована от процессора другого производителя).

    Например, процессор Zilog Z80 наследовал систему команд Intel 8080, расширил её и поменял мнемоники (и обозначения регистров) на свой лад. Процессоры Motorola Fireball наследовали систему команд Z80, несколько её урезав. Вместе с тем, Motorola официально вернулась к мнемоникам Intel и в данный момент половина ассемблеров для Fireball работает с мнемониками Intel, а половина — с мнемониками Zilog.

    Директивы

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *