Ассемблер
Материал из Lurkmore
« |
Нам не дано предугадать, как слово наше отзовется... | » |
— Ф. И. Тютчев программирует на Ассемблере |
Ассемблер или asm (англ. Assembler — сборщик) — утилита, транслирующая исходники программы на языке ассемблера собственно в машинный код, то есть на язык бездушной машины. Для обратного превращения существует дизассемблер (англ. Disassembler — разборщик, ломалка), широко используемый хакерами. Часто словом «ассемблер» называют сам язык ассемблера — простейший способ записи машинного кода с помощью расовых английских сокращений, называемых мнемониками (см. в конце статьи). Поскольку язык ассемблера привязан к устройству процессора, программы написанные на нем не являются переносимыми на иную компьютерную архитектуру, так как тип процессора жёстко определяет набор доступных команд машинного языка, но на это всем похуй, так как нет процессора кроме x86 и Intel пророк его.
Содержание |
[править] История
Когда компьютеры были большими как динозавры, а объем мозгов у них был примерно такой же, как у этих рептилий, и даже меньше, единственным способом программирования было забивание программы в память ЭВМ непосредственно в цифровом виде (иногда даже с помощью щелканья переключателями). Затем человек начал совершенствовать эту технику, постепенно перекладывая труд по генерации кода на плечи самой машины. Ибо заставлять высококвалифицированного человека перебирать биты и помнить кучу шестнадцатеричных (а то и восьмеричных) кодов обходится весьма дорого, как в деньгах, так и во времени.
Простейший транслятор (ассемблер первого поколения) позволял фактически просто писать машинные команды на «человеческом» языке, что позволило программерам немного расслабиться. Достаточно быстро туда добавились многочисленные свистелки и перделки, нарушающие Истинную Красоту Программирования На Ассемблере, но еще больше экономящие время и силы (а значит и деньги), как то макросы, библиотеки и прочее. Затем появились языки высокого уровня и компиляторы (более интеллектуальные генераторы кода с более понятного человеку языка) и интерпретаторы (исполнители человекописанной программы на лету). Которые совершенствовались, совершенствовались, совершенствовались, и досовершенствовались до «программирования мышкой», а компиляторы научились генерировать код, которому по скорости написанный человеком начал сливать[1]. Такие дела.
В целом история языков программирования протекает в направлении от программирования на языке компьютера до манипуляции абстракциями вродеПослать.Лесом(всех(кому не нравится эта статья))
Ну или (послать (лесом (всех (кому-не-нравится 'эта-статья'))))
или послать :: Куда -> [Люди] -> String послать куда = map (\x -> (show x) ++ ", иди " ++ (show куда)) кванторВкуса :: (ОбъектЧувства a) => ТипКвантора -> ТипОтношения -> a -> [Люди] посылаем :: String посылаем = let быдло = кванторВкуса Все НеНравится этаСтатья in послать быдло
На языке ассемблера этот код занял бы более 9000 строк. И потребовал бы долгой и кропотливой работы по своему созданию. Зато, в отличие от, оно бы работало, а не только свистело, пердело, выдавало красивые иконки и жрало 640K памяти.
[править] Асмофаги и быдлокодеры
Среди программистов с длинной бородой, видевших еще те компьютеры-динозавры, есть такие, которые очень трепетно относятся к напейсанию кода, и считают, что ассемблер — это труЪ, а языки высокого уровня — шлак и унылое говно, предназначенные исключительно для быдлокодерства. При упоминании факта, что современные компиляторы генерируют гораздо более быстрый код, начинают срать кирпичами и обзываться нехорошими словами, ибо сама мысль, что машина может быть умнее человека, считается недопустимой и кощунственной. При этом упускается тот факт, что компиляторы, вообще-то, пишут люди. Степень владения языком ассемблера считается мерилом отличия программиста от быдлокодера. Наиболее тяжелый клинический случай представляет молочный брат Линуса расовый финн Вилле Турьянмаа, написавший целую ОС — MenuetOS на чистом ассемблере. На ассемблере же была написана первая версия UNIX, коя им и не является по нынешним понятиям, так как позже была переписана чуть более, чем наполовину на C и помещена в анналы истории.
Тем не менее, программирование на языке ассемблера очень часто используется при написании программ, использующих возможности процессора, не реализуемые языками высокого уровня, а также программировании всевозможных нестандартных программистских хитростей. Драйвера для новых устройств тоже содержат в себе чуть менее, чем половину ассемблерного кода, коий при доведении их до ума ушастыми мартышками заменяют на стандартный C/C++. Часто компиляторы (чуть менее, чем все) предоставляют возможность вставлять ассемблерный код в текст программы. Алсо, ассемблер используется для программирования всевозможных микроконтроллеров и сигнальных процессоров, параллельно с С-компиляторами. В этом случае зачастую важна компактность кода и скорость работы, которых компилятор может не обеспечить. Также известно, что расовый браузер Хром написан на сипипи пополам с ассемблером, что кагбэ намекает (хром в сводной статистике всех направлений серфа считается самым быстрым браузером в мире).
Понятно, что писать что-либо крупное на ассемблере в современном мире не будет даже самый отъявленный маньяк, даже большинство фирмваря и прочих глюкалок для микроконтроллеров сейчас пишется на чем-то более продвинутом. Но когда стоимость каждого лишнего не то что мегабайта а полубайта в ОЗУ становится критичной (ибо их просто нет, например на каком-нибудь запущенном много лет назад спутнике до которого можно достучаться по радио, но никак физически), выливаются в миллиарды и даже жизни (встроенный софт бортовых систем в авиации и космонавтике) — ассемблер strikes back! К примеру, софт для кораблей «Союз ТМА-М», «Прогресс М-М» написаны на Си (по крайней мере российский сегмент МКС). ПО ЦВМов «Бурана» писалось на ПРОЛ-2. «Союз ТМА» — не на Си, у него БЦВК «Аргон-16», сначала программировали его на ассемблере, в поздних машинах транслировали на высокоуровневый язык. Спутники «Ямал» и «Белка» написаны на Си.
[править] Ассемблер и Линукс
Хотя программирование на ассемблере в Unix-мире считается моветоном, поскольку нарушает один из основополагающих принципов unix way «жертвуй производительностью ради переносимости», даже тут находится место разногласиям, способным вылиться в настоящую драму.
Дело в том, что встроенный ассемблер большинства Unix-ов (и Linux в том числе) использует синтаксис (AT&T-синтаксис), в корне отличающийся от оригинального Intel-синтаксиса. А поскольку Intel-синтаксис у большинства труЪ-линуксоидов прочно ассоциируется с маздаем, он объявляется ересью, и всем, кто пользуется nasm, yasm или fasm пророчатся вечные муки, страшный суд, ад и погибель, хотя gas тоже владеет интеловским синтаксисом. Правда все ELF-инфекторы всё же приходится писать на старом добром асме.
Алсо какой либо годной документации по ассемблеру AT&T в интернете хрен найдешь (зато на официальном сайте компании 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».
Алсо, в качестве исходника чат-бота Киса в фильме }{0TT@БЬ)Ч был показан исходник чат-бота Eliza на асме для калькулятора TI-83 Plus с процессором Z80.
[править] Область применения
- Популярен для допиливания зацикливаемых кусков программы… в роли напильника. Перепиливание критических участков кода может принести PROFIT, а может и не принести. В любом случае, заниматься таким перепиливанием стоит только тогда, когда у вас на руках уже полностью работающий алгоритм, который можно было бы ускорить, а не наоборот.
- Для использования новых команд, доступных в новых процессорах. Компилятор хоть и оптимизирует код высокого уровня при компиляции, но практически никогда не способен генерировать инструкции из расширенных наборов команд типа AVX, СTV, XOP и т.п. Потому что команды в процессоры добавляют быстрее, чем в компиляторах появляется логика для генерации этих команд.
- Используется для написания кода, создание которого невозможно (или затруднено) на языках высокого уровня, например, получение дампа памяти/стека. Даже когда аналог на языке высокого уровня возможен, профит от языка ассемблера может быть значительным. Например, реализация подсчета среднего суммы двух чисел с учётом переполнения для x86 процессоров занимает всего 2 команды (сложение с выставлением флага переноса и сдвиг с заёмом этого флага). Аналог на языке высокого уровня ((long) x + y) >> 1
- может не работать в принципе, если sizeof(long) == sizeof(int)
- при компиляции конвертируется в чуть менее чем дохрена команд процессора.
- Также может использоваться задротами для написания очень компактных программ. Пример: клиент для аськи, занимающий в скомпилированном виде 34 КБ. Другой пример: тоже IM-клиент Faim 0.21 — 12.61 КБ.
- В вузах изучается для закрепления знаний об устройстве компьютера.
- Является единственным языком программирования для создания достойных инфекторов — Cih, Sality, Sinowal.
- Чуть более чем половина программ для GPU пишутся на ассемблере, наряду с использованием языков высокого уровня HLSL или GLSL. Хороший, годный шейдер обязательно содержит асму, ибо GPU — это принципиально узкое место для выделения графической составляющей в монитор (Есть, конечно и более современные методы типа использования OpenCL, но всё же ASM << C).
- Довольно часто — для
написания программ для микроконтроллеров, ввиду их мизерного объема памятиповышения ЧСВ. Попробуй-ка напиши на какой-нибудь дельфи прогу, дабы влезла в 2кб флэша и 128б оперативки! Ну и такие гадкие вещи, как overhead. Программа на Си требует значительно больше оперативной памяти[ЩИТО?], значительно больше места во flash памяти[ЩИТО?], работает куда медленней чем ассемблерная программа[ЩИТО?]. И если на обычном компьютере с его гигагерцами частот, гигабайтами оперативки и дисковой памяти это не столь критично, то вот для контроллера с жалкими килобайтами флеша, у которого частота порой не превышает 16 мегагерц, а оперативки и килобайта не наберется, такой расход ресурсов более чем критичен. Кроме того существуют такие контроллеры как ATTiny 1x у которых либо вообще нет оперативки, либо она такая мизерная, что даже стек там сделан аппаратным, всего на три уровня. Так что на Си там ничего написать в принципе нельзя. Ложь, пиздёж и провокация. Анонимус самолично пишет проги для ATTiny13/ATTiny15/ATTiny2313/ATTiny24. Окромя динозавра ATTiny11 данная болезнь не замечена ни у одного из вышеперечисленных монстров RISC архитектуры. - Оптимизация невъебенно затратных математических алгоритмов. Часто встречается в исходниках фильтров для так любимого видеопиратами и анимэшниками винрарнейшего AviSynth.
- Промежуточный этап между неким левым синтаксисом (не обязательно даже языком, это может быть визуальный "конструктор" программы) и исполнимым кодом. Петя хочет анализ Фурье на ЦСП на участке в миллисекунду, а Вася в две? Нет проблем, нажимайте кнопочки и собирайте в проект полученные пятидесятиметровые ассемблерные сырцы, работающие с предельно возможной именно для конкретного случая скоростью. Не компилятор же отдельный писать ради Васи и Пети, честное слово.
[править] Пример программирования
Нижеследующий кусок кода переключает процессор из реального режима в длинный защищенный (пример для nasm):
BITS 16
; Тут шла длинная инициализация системных таблиц; прерывания запрещены, NMI блокировано
lidt [idtr_image] ; IDTR указывает на 64-битную таблицу прерываний
lgdt [gdtr_image] ; GDTR указывает на глобальную дескрипторную таблицу
mov eax,cr4 ; Установим CR4.PAE=1
or ax,20h
mov cr4,eax
mov ecx,0C0000080h ; Установим EFER.LME=1
rdmsr
or ax,100h
wrmsr
mov eax,[pml4_base] ; Установим CR3 на корневую таблицу страниц
mov cr3,eax
mov eax,cr0 ; Все готово. Установкой CR0.PE и CR0.PG включаем длинный режим
or eax,80000001h
mov cr0,eax
db 66h ; Это переводится как jmp far 0008:start_64
db 0eah ; Вписываем цыфирками, поскольку надо наставить нужных префиксов
dd start_64 ; Чистим очередь команд и прыгаем в 64-битный код
dw 08h
BITS 64
start_64: mov rsp,STACK_BASE ; установим стек
; Здесь хуярим 64-битный код...
Вообще, в среде ASM программистов существует целая война ассемблеров. Кто-то предпочитает nasm (распространяется нахаляву, из-за этого и приобрёл популярность у некоторых кодеров), кто-то tasm, masm или fasm. На самом деле вроде бы и ерундовая вещь, но каждый ассемблер имеет ряд ограничений, и в то же время некоторые другие особенные фичи. Поэтому не удивляйтесь, если кто-то будет с пеной у рта отстаивать свой ассемблер, или тому, что код, написанный под одну разновидность, на другой попросту не оттранслируется. Ассемблер имеет множество диалектов, некоторые из них довольно продвинуты, к примеру макросы fasm чем-то напоминают язык высокого уровня, поэтому он вызывает в среде ассемблерщиков некоторый баттхёрт, да ещё и ассоциации с хорошо оптимизированным и разбитым на отдельные операции с прямыми указателями Си делают контрольный выстрел.
[править] Мнение изучающей студентоты
На самом деле, соль Ассемблера в том, что он делает ВСЁ, кроме того, что нужно. Термин «Научиться программировать на Ассемблере» (см. ассемблировать, «оседлать», «обуздать», «поработить» Ассемблер) подразумевает вывод на протяжении долгого и попабольного обучения хитроумного плана, который позволит наебать Ассемблер незаметно для него, тем самым заставив его работать на вас. Судя по всему, успеха добиваются единицы. Остальные же, которые, не понимая того, становятся рабами Вышеназванного, теряют волю, сходят с ума и, в лучшем случае, попадают в армию.
[править] Алсо
- Эрик Дрекслер придумал самое любопытное наноустройство — ассемблер. Суть™ девайса в том, что он собирает продукт своей деятельности из отдельных атомов. Универсальный нанобот, как джинн из бутылки, сможет лечить людей, возводить сказочной красоты дворцы и выполнять всяческие прихоти.
Учитывая, какое значение в современной российской экономике имеет термин нанотехнологии, читатель сам может прикинуть сроки практической реализации идеи.
- Как упомянуто в заголовке, в переводе с расово-пиндосского Assembler означает сборщик. То есть в тех же СШП ассемблером может называться всё (неживое и живое), что занимается сборкой чего-либо.
[править] Галерея
[править] Ссылки
[править] Примечания
- ↑ Речь идёт только о последнем эшелоне оптимизации — оптимальном генерировании машинных операций. А в наше время узкое место и так давно уже не в нём, а в бездарной архитектуре комплексов ПО в целом, из-за чего машина занимается переливанием из пустого в порожнее — но с предельно оптимизированной скоростью струи, да — это в первую очередь. А еще очень негативно на скорости сказывается незнание быдлокодерами основ теории алгоритмов и структур данных. Второй пункт в последнее время нивелируется невъебенно навороченными стандартными (или специальными) библиотеками языков и сред разработки, что в конечном итоге способствует терминальному отупению тех же быдлокодеров и возвратом к пункту 1 этой ссылки
[ + ] Любой программист без словаря поймёт, что такое Ассемблер
|
|||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|