Язык ассемблера: различия между версиями

[непроверенная версия][отпатрулированная версия]
Содержимое удалено Содержимое добавлено
м пунктуация
Метка: редактор вики-текста 2017
дополнение, уточнение, стилевые правки, викификация
Строка 1:
{{Язык программирования}}
[[Файл:Motorola 6800 Assembly Language.png|thumb|250px|Листинг программы на языке ассемблера Motorola MC6800 (слева идут адреса и машинные коды в [[Шестнадцатеричная система счисления|шестнадцатеричной системе]], вычисленные и сгенерированные ассемблером из исходного кода программы, справа показан сам текст программы с мнемоническими инструкциями, метками, директивами, выражениями и комментариями)]]
 
'''Язы́к ассе́мблера''' ({{lang-en|assembly language}}) — машинно-ориентированный [[Низкоуровневый язык программирования|язык программирования низкого уровня]]. Его команды прямо соответствуют отдельным [[Код операции|командам машины]] или их последовательностям, также он может предоставлять дополнительные возможности облегчения программирования, такие как [[макрокоманда|макрокоманды]], выражения, средства обеспечения [[Модульность (программирование)|модульности программ]]. Может рассматриваться как '''автокод''' (см. ниже), расширенный конструкциями [[Высокоуровневый язык программирования|языков программирования высокого уровня]]<ref>СТ ИСО 2382/7-77 // {{книга|заглавие=Вычислительная техника. Терминология: Справочное пособие. Выпуск 1|ответственный=Рецензент канд. техн. наук Ю. П. Селиванов|место=М.|издательство=Издательство стандартов|год=1989|страниц=168|isbn=5-7050-0155-X|тираж=55&nbsp;000}}</ref><ref name="ГОСТ 19781-83">ГОСТ 19781-83 // {{книга|заглавие=Вычислительная техника. Терминология: Справочное пособие. Выпуск 1|ответственный=Рецензент канд. техн. наук Ю. П. Селиванов|место=М.|издательство=Издательство стандартов|год=1989|страниц=168|isbn=5-7050-0155-X|тираж=55&nbsp;000}}</ref>. Является существенно платформо-зависимым. Языки ассемблера для различных [[Аппаратная платформа компьютера|аппаратных платформ]] несовместимы, хотя могут быть в целом подобны.
 
Строка 27 ⟶ 26 :
Использование языка ассемблера предоставляет программисту ряд возможностей, как правило, недоступных при программировании на языках высокого уровня. Большинство из них связано с близостью языка к аппаратной платформе.
 
* Возможность максимально полного использования всех особенностей аппаратной платформы позволяет, теоретически, писать самый быстрый и компактный код из всех возможных для данного процессора. Искусный программист, как правило, способен значительно оптимизировать программу по сравнению с транслятором с языка высокого уровня по одному или нескольким параметрам и создать код, близкий к [[Эффективность по Парето|оптимальному по Парето]] (как правило, быстродействие программы достигается за счёт удлинения кода и наоборот):
** за счёт более рационального использования ресурсов процессора, например, максимально эффективного размещения всех или часто используемых исходных данных вво внутренних регистрах процессора, можно исключить излишние обращения к [[Оперативное запоминающее устройство|внешней оперативной памяти]];
** за счёт ручнойинтеллектуальной оптимизации вычислений, в том числе более эффективного использования промежуточных результатов, может быть сокращён объём кода и повышена скорость программы.
* Возможность непосредственного доступа к аппаратуре, и, в частности, [[порт ввода-вывода|портам ввода-вывода]], конкретным адресам памяти, регистрам процессора (впрочем, данная возможность существенно ограничивается тем, что во многих операционных системах прямое обращение из прикладных программ для записи в регистры периферийного оборудования блокировано для повышения надёжности работы системы).
 
Использование языка ассемблера практически не имеет альтернативы при создании:
 
* [[драйвер]]ов оборудования и [[Ядро операционной системы|ядра операционной системы]] (по крайней мере, машинозависимых подсистем ядра ОС), тогда, когда важнопринципиально необходимо временно́е согласование работы периферийных устройств с центральным процессором;
* программ, которые должны храниться в [[Постоянное запоминающее устройство|ПЗУ]] ограниченного объёма и/или выполняться на устройствах с ограниченной производительностью («[[прошивка|прошивок]]» компьютеров и различных электронных устройств);
* платформоплатформенно-зависимых компонентов [[компилятор]]ов и [[интерпретатор]]ов [[Язык программирования высокого уровня|языков высокого уровня]], системных библиотек и кода, реализующего совместимость [[Аппаратная платформа компьютера|платформ]].
 
Отдельно можно отметить, что сС помощью программы-[[дизассемблер]]а возможно преобразование откомпилированной программы в программу на языке ассемблера. В большинстве случаев это единственный (хотя и крайне трудоёмкий) способ [[Обратная разработка|обратного реконструирования]] алгоритмов программы, если не доступен её исходный код на языке высокого уровня.
 
== Ограничения ==
* В силу машинной ориентации («низкого уровня») языка ассемблера человеку сложнее читать и понимать программу написанную на нём по сравнению с языками программирования высокого уровня. Это серьёзно затрудняет сопровождение программ, написанных на языке ассемблера.
* Программа на языке ассемблера состоит из очень «мелких» элементов — машинных команд, соответственно, объём программы впо командахколичеству пропорциональнокоманд больше. Поскольку, как известно{{кому}}, программист за единицу времени может написать и отладить примерно одно и то же число операторов, вне зависимости от используемого языка, на котором он пишет, разработка на ассемблереязыке ассемблера больших программ оказывается существенно медленнее.
* Усложняются программирование и отладка кода, растут трудоёмкость создания кода и вероятность внесения ошибок при модификации.
* Требуется повышенная квалификация программиста для получения качественного кода: кодэффективность кода, написанныйнаписанного среднимначинающим программистом на языке ассемблера, обычно оказывается не лучше или даже хуже эффективности кода, порождаемого [[Оптимизирующий компилятор|оптимизирующим компилятором]] для сравнимых программ, написанных на языке высокого уровня<ref>{{cite web|author=Крис Касперски.|title=Война миров: Ассемблер против Си|url=http://www.insidepro.com/kk/145/145r.shtml|accessdate=1 июня 2010|archiveurl=https://web.archive.org/web/20100729161121/http://www.insidepro.com/kk/145/145r.shtml|archivedate=2010-07-29|deadlink=yes}}</ref>. При этом чем больше объём программы, тем меньше выигрыш от использования языка ассемблера.
* Программа на языке высокого уровня может быть перекомпилирована с автоматической оптимизацией под особенности новой целевой платформы<ref>Например, доступ к данным, [[Выравнивание данных|невыровненным]] на границу 32-битных слов в архитектуре [[IA-32]], требует дополнительного времени. Также, в архитектуре [[Intel P6]] появились два конвейера, и, чтобы они не {{translation2|простой конвейера|простаивали|en|Pipeline stall}}, может потребоваться {{translation|переупорядочивание инструкций||en|Compiler optimization#Factors affecting optimization}}</ref>, программа же на языке ассемблера на новой платформе может потерять своё преимущество в скорости без ручного переписывания кода<ref>{{cite web|author=Кирилл Кочетков.|title=MP3-кодек LAME — продолжаем исследования|url=http://www.ixbt.com/cpu/lame-exam-2.shtml|publisher=[[iXBT]]|date=28 ноября 2003|accessdate=1 июня 2010|archiveurl=https://web.archive.org/web/20120419015315/http://www.ixbt.com/cpu/lame-exam-2.shtml|archivedate=2012-04-19|deadlink=yes}}</ref><ref>{{cite web|author=Serj Kalichev.|title=Основы написания переносимого кода|url=http://www.opennet.ru/base/dev/porting_code.txt.html|accessdate=1 июня 2010|description=Оригинал статьи: Martin Husemann. Fighting the Lemmings|archiveurl=https://web.archive.org/web/20120513230747/http://www.opennet.ru/base/dev/porting_code.txt.html|archivedate=2012-05-13|deadlink=yes}}</ref>.
* Как правило, программисту доступно меньшее количество доступных [[библиотека (программирование)|библиотек]] по сравнению с современными индустриальнымиразвитыми и популярными языками программирования.
* Отсутствует переносимостьвозможность прямой простой переносимости программ на языке ассемблера на компьютеры с другой архитектурой и системой команд.
 
== Применение ==
Исторически, если первым поколением языков программирования считать машинные коды, то язык ассемблера можно рассматривать как второе поколение языков программирования. Недостатки языка ассемблера, сложность разработки на нём больших программных комплексов привели к появлению языков третьего поколения — [[Высокоуровневый язык программирования|языков программирования высокого уровня]] (таких как [[Фортран]], [[Лисп]], [[Кобол]], [[Паскаль (язык программирования)|Паскаль]], [[Си (язык программирования)|Си]] и др.). Именно языки программирования высокого уровня и их наследники в основном используются в настоящее время в индустрии [[информационные технологии|информационных технологий]]. Однако языки ассемблера сохраняютпродолжают свою нишуприменяться, обусловленнуючто обусловлено их уникальными преимуществами в части эффективности и возможности полного использования специфических средств конкретной платформы.
 
На языке ассемблера пишут программы или их фрагменты в тех случаях, когда критически важны:
* быстродействие, жто ([[драйвер]]ы устройств, компьютерные игры);
* объём используемой памяти (загрузочные секторы, встраиваемое ({{lang-en|embedded}}) программное обеспечение, программы для [[микроконтроллер]]ов и процессоров с ограниченными ресурсами, [[компьютерный вирус|вирусы]], программные защиты).
 
С использованием программирования на языке ассемблера производятся:
* Оптимизация критичных к скорости участков программ в программах на языках высокого уровня, таких как [[C++]] или [[Pascal]]. Это особенно актуально для [[Игровая приставка|игровых приставок]], имеющих фиксированнуюограниченную производительность, и для [[мультимедиа|мультимедийных]] [[кодек]]ов, которые стремятся делать менее ресурсоёмкими и более быстрыми.
* Создание [[операционная система|операционных систем]] (ОС) или их некоторых компонентов. В настоящее время подавляющее большинство ОС пишут на более высокоуровневых языках (в основном на [[Си (язык программирования)|Си]] — языке высокого уровня, который специально был создан для написания одной из первых версий [[UNIX]]). Аппаратно зависимые участки кода, такие как [[Загрузчик операционной системы|загрузчик ОС]], уровень [[Слой аппаратных абстракций|абстрагирования от аппаратного обеспечения]] (hardware abstraction layer) и ядро операционной системы, часто пишутся на языке ассемблера. Фактически, ассемблерного кода в ядрах [[Windows]] или [[Linux (ядро)|Linux]] совсем немного, поскольку авторы стремятся обеспечить [[Портирование программного обеспечения|переносимость]] и [[надёжность]], но тем не менее он там присутствует. Некоторые любительские ОС, например, такие как [[MenuetOS]] и [[KolibriOS]], целиком написаны на языке ассемблера. При этом MenuetOS и KolibriOS помещаются на дискету и содержат графический многооконный интерфейс{{источник}}.
* Программирование [[микроконтроллер]]ов (МК) и других встраиваемых в оборудование управляющих процессоров. По мнению профессора [[Таненбаум, Эндрю|Таненбаума]], развитие МК повторяет историческое развитие компьютеров новейшего времени<ref>Эндрю Таненбаум. Архитектура компьютера. 5-е изд.</ref>. Сейчас (2013 г.) для программирования МК весьма часто применяют язык ассемблера (хотя идля вэтого этой областиболее широкое распространение получают языки вроде Си). ВТипичная задача программы в МК приходится- перемещатьперемещение отдельныеотдельных [[байт]]ы и [[бит]]ы между различными [[ячейка памяти|ячейками памяти]] и [[Логическая операция|логические операции]] с ними. Программирование МК весьма важно, так как, по мнению Таненбаума, в автомобиле и квартирежилище современного цивилизованного человека в среднем содержится 50 микроконтроллеров<ref>Эндрю Таненбаум. Архитектура компьютера. 3-е изд.</ref>.
* Создание [[драйвер]]ов. Драйверы (или их некоторые программные модули) обычно программируют на языке ассемблера. Хотя в настоящее время драйверы также стремятся писать на языках высокого уровня (на высокоуровневом языке много проще написать надёжный драйвер) в связи с повышенными требованиями к надёжности и достаточной производительностью современных процессоров (быстродействие обеспечивает временно́е согласование процессов в устройстве и процессоре) и достаточным совершенством компиляторов с языков высокого уровня (отсутствие ненужных пересылок данных в сгенерированном коде), подавляющая часть современных драйверов пишется на языке ассемблера. Надёжность для драйверов играет особую роль, поскольку в [[Windows NT]] и [[UNIX]] (в том числе в [[Linux]]) драйверы работают в режиме ядра системы. Одна тонкая ошибка в критичном для работы системы драйвере может привести к краху всей системы.
* Создание [[антивирусная программа|антивирусов]] и других защитных программ.
* Написание кода низкоуровневых библиотек [[транслятор]]ов языков программирования.
* Наисание компьютерных вирусов.
 
=== Связывание программ на разных языках ===
Поскольку уже давно на языке ассемблера часто кодируют только фрагменты программ, их необходимо [[связывание программ|связывать]] с остальными частями программной системы, написанными на других языках программирования. Это достигается двумя основными способами:
* На этапе компиляции — вставка в исходный код программы на языке высокого уровня ассемблерных фрагментов ({{lang-en|inline assembler}}) с помощью специальных директив высокоуровнего языка. Способ удобен для несложных преобразований данных, но полноценного ассемблерного кода с данными и подпрограммами, включая подпрограммы со множеством входов и выходов, не поддерживаемых языком высокого уровня, с его помощью сделать невозможно.
* На этапе [[Компоновщик|компоновки]] при [[Компилятор#Раздельная компиляция|раздельной компиляции]]. Для взаимодействия компонуемых модулей достаточно, чтобы импортируемые функции (определённые в одних модулях и используемые в других) поддерживали определённое [[соглашение о вызове]] ({{lang-en|calling conventions}}). Написаны же отдельные модули могут быть на любых языках, в том числе и на языке ассемблера.
 
Строка 81:
* Команды вызова [[Прерывание|прерываний]] (иногда относят к командам управления): <code>int</code>
* Команды ввода-вывода в [[порт ввода-вывода|порты]] (<code>in</code>, <code>out</code>)
* Для микроконтроллеров и [[микрокомпьютер]]ов характерны также команды, выполняющие проверку и переход по условию, например некоторые из них:
:* <code>cjne</code> — перейти, если не равно
:* <code>djnz</code> — декрементировать, и если результат ненулевой, то перейти
Строка 99:
* если изначально существовало два стандарта записи мнемоник (система команд была наследована от процессора другого производителя).
 
Например, процессор [[Zilog Z80]] наследовалунаследовал систему команд [[8080|Intel 8080]], расширил её и поменял мнемоники (и обозначения регистров) на свой лад. Процессоры [[Motorola Fireball]] наследовалиунаследовали систему команд Z80, несколько её урезавсократив. Вместе с тем, [[Motorola]] официально вернулась к мнемоникам [[Intel]] и в данный момент половина ассемблеров для Fireball работает с мнемониками от Intel, а половина — с мнемониками от Zilog.
 
=== Директивы ===
Строка 109:
* [[макрос в языке ассемблера|макросы]].
 
=== ПримерПримеры программыпрограмм ===
Примеры программы [[Hello, world!]] для разных платформ и разных диалектов:
{{Hider hiding
Строка 382:
 
== История и терминология ==
Данный тип языков получил своё название от названия [[транслятор]]а ([[компилятор]]а) с этих языков — ассемблераназываемом ассемблером ({{lang-en|assembler}} — сборщик). Название обусловлено тем, что программа «автоматически собиралась», а не вводилась вручную покомандно непосредственно в [[машинный код|кодах]]. При этом наблюдается путаница терминов: ассемблером нередко называют не только транслятор, но и соответствующий язык программирования (не совсем корректно - «программа на ассемблере», правильно - «программа на языке ассемблера»).
 
Использование термина «язык ассемблера» также может вызвать ошибочное мнение о существовании некоего единого языка низкого уровня или хотя бы стандартовстандарта на такиетакой языкиязык. ПриНе именованиисуществует единого языка ассемблера. При использовании термина "язык ассемблера", если не очевидно из контекста, желательно уточнять, ассемблер для какой [[Архитектура компьютера|архитектуры]] имеется в виду.
 
== Примечания ==