Для чего используют программы ассемблеры

Почему Ассемблер — это круто, но сложно

Потому что это круто. Но сложно.

Есть высокоуровневые языки — это те, где вы говорите if — else, print, echo, function и так далее. «Высокий уровень» означает, что вы говорите с компьютером более-менее человеческим языком. Другой человек может не понять, что именно у вас написано в коде, но он хотя бы сможет прочитать слова.

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

Ассемблер — это собирательное название языков низкого уровня: код всё ещё пишет человек, но он уже гораздо ближе к принципам работы компьютера, чем к принципам мышления человека.

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

Как мыслит процессор

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

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

Регистры бывают разного вида и назначения: одни служат, чтобы хранить информацию; другие сообщают о состоянии процессора; третьи используются как навигаторы, чтобы процессор знал, куда идти дальше, и так далее. Подробнее — в расхлопе ↓

Общего назначения. Это 8 регистров, каждый из которых может хранить всего 4 байта информации. Такой регистр можно разделить на 2 или 4 части и работать с ними как с отдельными ячейками.

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

Регистр флагов. Флаг — какое-то свойство процессора. Например, если установлен флаг переполнения, значит процессор получил в итоге такое число, которое не помещается в нужную ячейку памяти. Он туда кладёт то, что помещается, и ставит в этот флаг цифру 1. Она — сигнал программисту, что что-то пошло не так.

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

Сегментные регистры. Нужны были для того, чтобы работать с оперативной памятью и получать доступ к любой ячейке. Сейчас такие регистры имеют по 32 бита, и этого достаточно, чтобы получить 4 гигабайта оперативки. Для программы на Ассемблере этого обычно хватает.

Так вот: всё, с чем работает Ассемблер, — это команды процессора, переменные и регистры.

Здесь нет привычных типов данных — у нас есть только байты памяти, в которых можно хранить что угодно. Даже если вы поместите в ячейку какой-то символ, а потом захотите работать с ним как с числом — у вас получится. А вместо привычных циклов можно просто прыгнуть в нужное место кода.

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

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

Любая команда на этом языке выглядит так:

Метка — это имя для фрагмента кода. Например, вы хотите отдельно пометить место, где начинается работа с жёстким диском, чтобы было легче читать код. Ещё метка нужна, чтобы в другом участке программы можно было написать её имя и сразу перепрыгнуть к нужному куску кода.

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

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

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

mov eax, ebx ; Пересылаем значение регистра EBX в регистр EAX mov x, 0 ; Записываем в переменную x значение 0 add eax, х ; Складываем значение регистра ЕАХ и переменной х, результат отправится в регистр ЕАХ

Здесь нет меток, первыми идут команды (mov или add), а за ними — операнды и комментарии.

Пример: возвести число в куб

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

Первый вариант

mov al, x ; Пересылаем x в регистр AL imul al ; Умножаем регистр AL на себя, AX = x * x movsx bx, x ; Пересылаем x в регистр BX со знаковым расширением imul bx ; Умножаем AX на BX. Результат разместится в DX:AX

Второй вариант

mov al, x ; Пересылаем x в регистр AL imul al ; Умножаем регистр AL на себя, AX = x * x cwde ; Расширяем AX до EAX movsx ebx, x ; Пересылаем x в регистр EBX со знаковым расширением imul ebx ; Умножаем EAX на EBX. Поскольку x – 1-байтовая переменная, результат благополучно помещается в EAX

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

на худой конец x = x*x*x.

Хитрость в том, что когда каждая из этих строк будет сведена к машинному коду, этого кода может быть и 5 команд, и 10, и 50, и даже 100. Чего стоит вызов объекта Math и его метода pow: только на эту служебную операцию (ещё до самого возведения в куб) может уйти несколько сотен и даже тысяч машинных команд.

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

Почему это круто

Ассемблер позволяет работать с процессором и памятью напрямую — и делать это очень быстро. Дело в том, что в Ассемблере почти не тратится зря процессорное время. Если процессор работает на частоте 3 гигагерца — а это примерно 3 миллиарда процессорных команд в секунду, — то очень хороший код на Ассемблере будет выполнять примерно 2,5 миллиарда команд в секунду. Для сравнения, JavaScript или Python выполнят в тысячу раз меньше команд за то же время.

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

Справедливости ради отметим, что современные компиляторы С++ дают машинный код, близкий по быстродействию к Ассемблеру, но всё равно немного уступают ему.

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

Для того, чтобы писать программы на Ассемблере, нужно очень любить кремний:

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

Для чего всё это

Ассемблер незаменим в таких вещах:

На самом деле на Ассемблере можно даже запилить свой сайт с форумом, если у программиста хватает квалификации. Но чаще всего Ассемблер используют там, где даже скорости и возможностей C++ недостаточно.

Источник

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

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

Содержание

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

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

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

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

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

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

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

Достоинства

Недостатки

Применение

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

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

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

Нелегальная сфера деятельности

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

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

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

Это достигается 2 основными способами:

Синтаксис

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

Набор команд

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

Инструкции

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

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

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

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

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

Директивы

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

Пример программы

Примеры программы Hello, world! для разных платформ и разных диалектов: Шаблон:Hider hiding

Происхождение и критика термина «язык ассемблера»

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

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

В СССР язык ассемблера ранее называли «автокод».

Источник

Что такое ассемблер и нужно ли его изучать

Этому языку уже за 70, но на пенсию он пока не собирается.

Полина Суворова для Skillbox Media

Есть традиция начинать изучение программирования с вывода на экран строки «Hello world!». На языке Python, например, это всего одна команда:

Всё просто, понятно и красиво! Но есть язык программирования, в котором, чтобы получить тот же результат, нужно написать солидный кусок кода:

Это ассемблер. Только не нужно думать, что он плох. Просто Python — это язык высокого уровня, а ассемблер — низкого. Одна команда Python при выполнении вызывает сразу несколько операций процессора, а каждая команда ассемблера — всего одну операцию.

Сложно? Давайте разбираться.

Программист, консультант, специалист по документированию. Легко и доступно рассказывает о сложных вещах в программировании и дизайне.

Немного о процессорах и машинном языке

Чтобы объяснить, что такое язык ассемблера, начнём с того, как вообще работает процессор и на каком языке с ним можно «разговаривать».

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

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

Например, для Intel 8088 инструкция 0000001111000011B — это операция сложения двух чисел, а 0010101111000011B — вычитания.

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

Поэтому много лет назад был создан язык ассемблера, в котором коды операций обозначались буквами и сокращениями английских слов, отражающих суть команды. Например, команда mov ax, 6 означает: «переместить число 6 в ячейку памяти AX».

Когда и как был создан ассемблер?

Это произошло ещё в сороковых годах прошлого века. Ассемблер был создан для первых ЭВМ на электронных лампах, программы для которых писали на машинном языке. А так как памяти у компьютеров было мало, то команды вводили, переключая тумблеры и нажимая кнопки. Даже несложные вычисления занимали много времени.

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

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

Как устроен язык ассемблера?

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

Коды операций в языке ассемблера мнемонические, то есть удобные для запоминания:

Регистрам и ячейкам памяти присваиваются символические имена, например:

EAX, EBX, AX, AH — имена для регистров;

meml — имя для ячейки памяти.

Например, так выглядит команда сложения чисел из регистров AX и BX:

А это команда вычитания чисел из регистров AX и BX:

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

Вот некоторые из них:

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

Вот, например, код, на ассемблере, выводящий на экран цифры от 1 до 10:

Здесь действие будет выполняться в цикле — как, например, в циклах for или do while в языках высокого уровня.

Единого стандарта для языков ассемблера нет. В работе с процессорами Intel разработчики придерживаются двух синтаксисов: Intel и AT&T. Ни у того ни у другого нет особых преимуществ: AT&T — стандартный синтаксис в Linux, а Intel используется в мире Microsoft.

Одна и та же команда в них выглядит по-разному.

Например, в синтаксисе Intel:

mov eax, ebx — команда перемещает данные из регистра eax в регистр ebx.

В синтаксисе AT&T эта команда выглядит так:

Почему для разных семейств процессоров нужен свой ассемблер?

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

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

Кому и зачем нужен язык ассемблера?

Даже из нашего примера «Hello, World!» видно, что ассемблер не так удобен в разработке, как языки высокого уровня. Больших программ на этом языке сейчас никто не пишет, но есть области, где он незаменим:

Если вы хотите разрабатывать новые микропроцессоры или стать реверс-инженером, то есть смысл серьёзно заняться изучением языка ассемблера.

Востребованы ли программисты на ассемблере сегодня?

Конечно. Хотя на сайтах по поиску работу вы вряд ли найдёте заявки от работодателей с заголовками: «Нужен программист на ассемблере», зато там много таких, где требуется знание ассемблера дополнительно к языкам высокого уровня: C, C++ или Python. Это вакансии реверс-инженеров, специалистов по компьютерной безопасности, разработчиков драйверов и программ для микроконтроллеров/микропроцессоров, системных программистов и другие.

Предлагаемая зарплата — обычная в сфере IT: 80–300 тысяч рублей в зависимости от квалификации и опыта. Вот, например, вакансия реверс-инженера на HeadHunter, где требуется знание ассемблера:

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

Нет, так делать не нужно. Для этого есть несколько причин:

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

Микропроцессор, выпущенный компанией Intel в 1979 году. Использовался в оригинальных компьютерах IBM PC.

Данные, которые обрабатываются командой — грамматической конструкцией языка программирования, обозначающей аргумент операции.

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

Программа, которая обеспечивает загрузку самой OC сразу после включения компьютера.

Источник

Для чего нужен ассемблер?

Скажем так: зачем уметь собирать-разбирать двигатель от машины и понимать как он работает?
99% людей это не нужно в принципе. Но если вы это знаете, вы можете легко диагностировать какую-то проблему, понять как её решить. При этом, каждый день вы не производите двигатели на станке.

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

К вашему сведению драйверы это часть ОС. Их как и всю ОС можно написать на СИ, можно на Assembler, а можно, например, на Pascal. Просто сейчас компьютеры настолько быстрые и имеют так много памяти, что оптимизация кода уходит на второй план. Хотя компиляторы современных языков программирования в плане оптимизации фору дадут большинству современных программистов.
Но все таки в серьезных программах есть много так называемых»узких мест» как правило это связано с нехваткой быстродействия, реже нехваткой памяти, тут на помощь приходит ассемблер.
Хотя чудику который говнокодит на PHP или JS этого не понять

PS Язык программирования это инструмент, а не стихотворение его учить не надо, на нем надо писать программы

Источник

Погружение в ассемблер. Зачем учить ассемблер в 2020 году

Содержание статьи

Погружение в ассемблер

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

Ради чего стоит изучать ассемблер?

Сто­ит осво­ить ассем­блер, если ты хочешь:

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

Кто выдаст лучший ассемблерный код?

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

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

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

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

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

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

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

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

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

При этом иног­да опти­мизи­рующий ком­пилятор вып­левыва­ет ассем­блер­ный код, логика которо­го ну сов­сем непонят­на. Одна­ко не спе­ши обви­нять ком­пилятор в глу­пос­ти. Давай раз­берем при­мер.

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

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

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

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

Ты при желании можешь написать на ассем­бле­ре даже веб‑сайт. В девянос­тые С был впол­не разум­ным выбором для этой цели. Исполь­зуя такую вещь, как CGI BIN, веб‑сер­вер мог вызывать прог­рамму, написан­ную на С. Через stdin сайт получал зап­рос, а через stdout отправ­лял резуль­тат в бра­узер. Ты можешь лег­ко реали­зовать тот же прин­цип на ассем­бле­ре.

Но зачем? Ты дол­жен быть мазохис­том, что­бы про­делы­вать такое. Потому что ког­да ты пишешь на ассем­бле­ре, то стал­кива­ешь­ся вот с такими проб­лемами.

Да, все мож­но написать на ассем­бле­ре. Но сегод­ня это нецеле­сооб­разно. Луч­ше пиши на С. Ско­рее все­го, будет безопас­нее, быс­трее и более лаконич­но.

От редакции

Ав­тор статьи — боль­шой пок­лонник С и нас­тоятель­но рекомен­дует этот язык. Мы не будем лишать его такой воз­можнос­ти. С — отличная шту­ка и помога­ет как осво­ить основные кон­цепции прог­рамми­рова­ния, так и про­чувс­тво­вать прин­ципы работы компь­юте­ра. Одна­ко при выборе язы­ка для изу­чения ты можешь руководс­тво­вать­ся самыми раз­ными сооб­ражени­ями. Нап­ример:

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

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

Какие преимущества ассемблер дает программисту?

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

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

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

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

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

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

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

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

Од­нако я бы не совето­вал начинать с ассем­бле­ра и более низ­ких сло­ев. Во всем том, что перечис­лено в двух пре­дыду­щих абза­цах, лег­че разоб­рать­ся, ког­да ты начина­ешь с какого‑нибудь язы­ка высоко­го уров­ня. Так ты дос­тигнешь жела­емо­го резуль­тата быс­трее, чем оно тебе нас­кучит.

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

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

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

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

Есть толь­ко память. При­чем ты работа­ешь с ней не так, как на язы­ке высоко­го уров­ня. Ты можешь забыть, что в какую‑то область памяти помес­тил стро­ку, и обра­тить­ся к ней как к чис­лу. Прог­рамма все рав­но ском­пилиру­ется. Но толь­ко обру­шит­ся в ран­тай­ме. При­чем обру­шит­ся жес­тко, без веж­ливого сооб­щения об ошиб­ке.

Но! Изу­чив ассем­блер, ты будешь понимать, как реали­зуют­ся и фун­кции, и цик­лы, и все осталь­ное. А раз­ница меж­ду переда­чей парамет­ра «по зна­чению» и «по ссыл­ке» ста­нет для тебя само­оче­вид­ной. Плюс если ты пишешь на С, но не можешь до кон­ца разоб­рать­ся, как работа­ют ука­зате­ли, то, ког­да ты узна­ешь, что такое регис­тры и отно­ситель­ная адре­сация, уви­дишь, что понять ука­зате­ли сов­сем нет­рудно.

Луч­ше начинай с С. На нем удоб­но осва­ивать осно­вы: перемен­ные, усло­вия, цик­лы, логичес­кие пос­тро­ения и осталь­ное. Опыт, который ты получишь при изу­чении С, лег­ко скон­верти­ровать на любой дру­гой язык высоко­го уров­ня, будь то Java, Python или какой‑то еще. Да и с ассем­бле­ром лег­че разоб­рать­ся, ког­да ты уже осво­ил С.

Насколько доходно уметь программировать на ассемблере?

Ес­ли заг­лянешь на HH.ru, то, ско­рее все­го, не най­дешь ни одной вакан­сии, у которой в заголов­ке написа­но сло­во «ассем­блер». Но вре­мя от вре­мени какая‑нибудь кон­тора лихора­доч­но ищет мага‑вол­шебни­ка, который зна­ет нут­ро компь­юте­ра нас­толь­ко глу­боко, что может пол­ностью под­чинить опе­раци­онную сис­тему сво­ей воле. Мага‑вол­шебни­ка, который уме­ет (1) латать сис­тему, не имея на руках исходно­го кода, (2) перех­ватывать потоки дан­ных на лету и вме­шивать­ся в них.

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

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

«Ког­да ты получа­ешь котиров­ки, про­ходя через весь стек TCP/IP, это слиш­ком мед­ленно», — говорят пар­ни из этой фир­мы. Поэто­му у них есть при­моч­ка, которая перех­ватыва­ет тра­фик на уров­не Ethernet, пря­мо внут­ри сетевой кар­ты, куда залита кас­томизи­рован­ная про­шив­ка.

Но эти ребята пош­ли еще даль­ше. Они собира­ются раз­работать девайс для филь­тра­ции тра­фика Ethernet — на ПЛИС. Зачем? Что­бы ловить котиров­ки на аппа­рат­ном уров­не и тем самым эко­номить дра­гоцен­ные мик­росекун­ды трей­дин­гового вре­мени и в ито­ге получать неболь­шое, очень неболь­шое пре­иму­щес­тво перед кон­курен­тами. Язык С им не подошел. Им даже ассем­блер не подошел. Так что эти пар­ни выцара­пыва­ют прог­рамму пря­мо на крем­нии!

Источник

Понравилась статья? Поделиться с друзьями:

Не пропустите наши новые статьи:

  • Для чего используют программу abbyy finereader
  • Для чего используют программу abbyy finereader информатика
  • для чего используют два монитора опытные программисты
  • Для чего используют linux
  • Для чего используют java язык программирования

  • Операционные системы и программное обеспечение
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest
    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии