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

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

Для чего нужен ассемблер. Смотреть фото Для чего нужен ассемблер. Смотреть картинку Для чего нужен ассемблер. Картинка про Для чего нужен ассемблер. Фото Для чего нужен ассемблер

Скажем так: зачем уметь собирать-разбирать двигатель от машины и понимать как он работает?
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 — на ПЛИС. Зачем? Что­бы ловить котиров­ки на аппа­рат­ном уров­не и тем самым эко­номить дра­гоцен­ные мик­росекун­ды трей­дин­гового вре­мени и в ито­ге получать неболь­шое, очень неболь­шое пре­иму­щес­тво перед кон­курен­тами. Язык С им не подошел. Им даже ассем­блер не подошел. Так что эти пар­ни выцара­пыва­ют прог­рамму пря­мо на крем­нии!

Источник

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

Этому языку уже за 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 сразу после включения компьютера.

Источник

За что я люблю ассемблер?

Этой статье уже почти 3 года. Однако сегодня я решил подредактировать её, дополнить и выложить, наконец, на Хабр.

Для чего нужен ассемблер. Смотреть фото Для чего нужен ассемблер. Смотреть картинку Для чего нужен ассемблер. Картинка про Для чего нужен ассемблер. Фото Для чего нужен ассемблер

Оговорочки

Хочу сразу оговориться, что правильно говорить не «ассемблер» (assembler), а «язык ассемблера» (assembly language), потому как ассемблер – это транслятор кода на языке ассемблера (т.е. по сути, программа MASM, TASM, fasm, NASM, UASM, GAS и пр., которая компилирует исходный текст на языке ассемблера в объектный или исполняемый файл). Тем не менее, из соображения краткости многие, говоря «ассемблер» (асм, asm), подразумевают именно «язык ассемблера».

Синтаксис директив, стандартных макросов и пр. структурных элементов различных диалектов (к примеру, MASM, fasm, NASM, GAS), могут отличаться довольно существенно. Мнемоники (имена) инструкций (команд) и регистров, а также синтаксис их написания для одного и того же процессора примерно одинаковы почти во всех диалектах (заметным исключением среди популярных ассемблеров является разве что GAS (GNU Assembler) в режиме синтаксиса AT&T для x86, где к именам инструкций могут добавляться суффиксы, обозначающие размер обрабатываемых ими данных, что бывает довольно удобно, но там есть и другие нюансы, сбивающие с толку программиста, привыкшего к классическому ассемблеру, к примеру, иной порядок указания операндов, хотя всё это лечится специальной директивой переключения в режим классического синтаксиса Intel).

Поскольку ассемблер – самый низкоуровневый язык программирования, довольно проблематично написать код, который корректно компилировался бы для разных архитектур процессоров (например, x86 и ARM), для разных режимов одного и того же процессора (16-битный реальный режим, 32-битный защищённый режим, 64-битный long mode; а ещё код может быть написан как с использованием различных технологий вроде SSE, AVX, FMA, BMI и AES-NI, так и без них) и для разных операционных систем (Windows, Linux, MS-DOS). Хоть иногда и можно встретить «универсальный» код (например, отдельные библиотеки), скажем, для 32- и 64-битного кода ОС Windows (или даже для Windows и Linux), но это бывает нечасто. Ведь каждая строка кода на ассемблере (не считая управляющих директив, макросов и тому подобного) – это отдельная инструкция, которая пишется для конкретного процессора и ОС, и сделать кроссплатформенный вариант можно только с помощью макросов и условных директив препроцессора, получая в итоге порой весьма нетривиальные конструкции, сложные для понимания.

Откуда растут ноги?

Ассемблером я увлёкся лет в 12–13, и он меня изрядно «затянул». Почему?

Во-первых, экономия памяти (дисковой и оперативной) и погоня за скоростью в те DOS-овские времена далёких 90-х годов были куда более актуальными темами, чем сейчас.

Во-вторых (и это более существенно), на ассемблере можно было делать много того, что сделать на языках высокого уровня (ЯВУ, не путайте с Java) нельзя, затруднительно или не так эффективно. К примеру, мне очень нравилось писать резидентные программы.

Но с тех пор прошло уже более 2-х десятков лет, и сейчас экономия памяти (особенно дисковой) в подавляющем большинстве случаев уже не так актуальна, да и скорости современных процессоров для выполнения повседневных задач вполне хватает (популярность языков сверхвысокого уровня подтверждает это, хотя закон Вирта никто не отменял). А современные компиляторы зачастую могут оптимизировать код по скорости даже лучше человека. Что же может привлекать программиста в ассемблере, ведь исходники на нём гораздо более объёмные и сложные, а на разработку требуется больше времени и внимания (в т.ч. на отладку)?

Вон оно что!

Приведу свои доводы относительно того, чем так хорош ассемблер.

Ассемблер даёт полный контроль над кодом и обладает большей гибкостью, чем любой другой язык программирования (даже C/C++). На асме мы можем конструировать нашу программу, размещая блоки кода и данных как нам вздумается. Каждый генерируемый байт будет таким, каким мы хотим его видеть. Без лишнего runtime-кода стандартных библиотек. Правда, справедливости ради отмечу, что необходимость в этом может возникнуть лишь в весьма специфических случаях. Однако существуют аппаратные платформы с ограниченными ресурсами, где оптимизация кода важна и актуальна и в наши дни.

На ассемблере можно написать ВСЁ, он всемогущ! Вряд ли у вас получится создать MBR-загрузчик полностью на C или на чём-то ещё. Для работы с железом на низком уровне, программирования чипсетов зачастую может потребоваться ассемблер. Для внедрения кода в другие процессы (injection, не только с вредоносными целями), создания различных антиотладочных приёмов тоже необходим ассемблер. Или, скажем, для проделывания чего-то вроде этого. Для C/C++ имеются интринсики – функции для генерации отдельных инструкций процессора (есть ли что-то подобное для других языков программирования – не знаю, не встречал). Но их частое использование загромождает код (не проще ли тогда писать на чистом ассемблере?) А их отсутствие не позволяет нам контролировать генерируемый компилятором код (при этом, к слову говоря, Visual C/C++, GNU C/C++ и Clang будут генерировать разный код; и даже один и тот же компилятор с разными настройками выдаст различный результат).

Обычно одна строка кода на ЯВУ разворачивается в несколько (или даже десяток) инструкций процессора. А знаете ли вы о том, что некоторые инструкции процессора Intel требуют несколько строк для реализации на ЯВУ (на том же C/C++, если не использовать интринсики)? Если не знаете, просто поверьте на слово, а я, возможно, напишу об этом в одной из следующих статей. Приведу лишь один простой пример: аналоги инструкций rol, ror (существующих ещё в самых ранних процессорах i8086 с конца 70-х годов) появились только в стандарте C++20 в библиотеке bit (как функции std::rotl, std::rotr), а в большинстве других языков они вообще отсутствуют.

Есть такое направление компьютерного искусства: демосцена. Написать intro, уместив исполняемый файл в 256 байт [1, 2, 3, 4] (а то и 128, 64, 32 или даже ещё меньше) на чём-то отличном от ассемблера (ну или по крайней мере, без использования ассемблера для финальной корректировки кода) вы вряд ли сможете.

Ещё одна интересная область применения ассемблера – создание файлов данных с помощью макросов и директив генерации данных. К примеру, fasm позволяет создавать виртуальные данные и генерировать отдельные файлы (директива virtual), а также читать и изменять ранее сгенерированный код (директивы load, store). Есть даже примеры AES-шифрования файлов.

Без ассемблера не обойтись при исследовании (reverse engineering), а зачастую и при отладке программ.

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

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

Но иногда использование ассемблера действительно оправдано (пример). Часто ассемблер хорошо использовать в виде вставок в код на ЯВУ (посмотрите RTL-модули Delphi, там этого добра в изобилии). Да и использование интринсиков, как правило, не имеет смысла (или даже опасно) без знания ассемблера.

Подытожим…

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

Создание загрузчиков, прошивок устройств (комплектующих ПК, встраиваемых систем), элементов ядра ОС.

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

Внедрение кода в процессы (injection), как с вредоносной целью, так и с целью защиты или добавления функционала. Системный софт.

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

Оптимизация кода по скорости, в т.ч. векторизация (SSE, AVX, FMA), математические вычисления, обработка мультимедиа, копирование памяти.

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

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

При создании компиляторов и трансляторов исходного кода с какого-либо языка на язык ассемблера (например, многие компиляторы C/C++ позволяют выполнять такую трансляцию). При создании отладчиков, дизассемблеров.

Собственно, отладка, дизассемблирование, исследование программ (reverse engineering).

Создание файлов данных с помощью макросов и директив генерации данных.

Вы не поверите, но ассемблер можно использовать и для написания обычного прикладного ПО (консольного или с графическим интерфейсом – GUI), игр, драйверов и библиотек 🙂

Быть или не быть?

Так, нужно ли изучать ассемблер современному программисту? Если вы уже не новичок в программировании, и у вас серьёзные амбиции, то изучение ассемблера, внутреннего устройства операционных систем и функционирования железа (особенно процессоров, памяти), а также использование различных инструментов для дизассемблирования, отладки и анализа кода полезно тем, кто хочет писать действительно эффективные программы. Иначе будет сложно в полной мере понять, что происходит «под капотом» любимого компилятора (хотя бы в общих чертах), как оптимизировать программы на любом языке программирования и какой приём стоит предпочесть. Необязательно погружаться слишком глубоко в эту тему, если вы пишете на Python или JavaScript. А вот если ваш язык – C или C++, хорошенько изучить ассемблер будет полезно.

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

Это будет полезно

Для чего нужен ассемблер. Смотреть фото Для чего нужен ассемблер. Смотреть картинку Для чего нужен ассемблер. Картинка про Для чего нужен ассемблер. Фото Для чего нужен ассемблер

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

Зубков С.В. Assembler для DOS, Windows и Unix. – ДМК Пресс, 2017. – 638 c., ISBN 978–5–97060–535–6.

Руслан Аблязов. Программирование на ассемблере на платформе x86–64. – ДМК Пресс, 2016. – 302 с., ISBN 978–5–97060–364–2.

Статьи старого WASM’а – кладезь обучающего материала на самые разные низкоуровневые темы (крайне рекомендую!)
Новый WASM (форум по низкоуровневому программированию и сборник статей).

Книги и статьи Криса Касперски (много).

Официальная документация AMD (множество документов) [всё на английском, PDF].

Архитектура и система команд микропроцессоров x86 (староватая документация на русском языке; из описания расширений есть только x87, MMX, 3DNow! и SSE(1)).

Марк Руссинович, Дэвид Соломон, Алекс Ионеску. Внутреннее устройство Microsoft Windows. – 6-е изд., часть 1. – Питер, 2013. – 800 с., ISBN 978–5–496–00434–3, 978–5–459–01730–4 (англ.: 978–0735648739).
Вышло 7-е издание этой части с Павлом Йосифовичем в качестве ещё одного соавтора – Питер, 2018 – 944 с., ISBN 978–5–4461–0663–9 (англ.: 978–3864905384).

Марк Руссинович, Дэвид Соломон, Алекс Ионеску. Внутреннее устройство Microsoft Windows. Основные подсистемы ОС. – 6-е изд., часть 2. – Питер, 2014. – 672 с., ISBN 978–5–496–00791–7 (англ.: 978–0735665873).
7-е издание этой части есть пока только на английском языке (ISBN 978–0135462409).

Джеффри Рихтер. Windows для профессионалов. Создание эффективных Win32-приложений с учётом специфики 64-разрядной версии Windows. – 4-е изд. – Питер, Русская редакция, 2001. – 752 с. (есть вариант книги 2008 г. на 720 с., но она тоже 4-го издания, с переводом 2000 года… в чём разница?), ISBN 5–272–00384–5, 978–5–7502–0360–4 (англ.: 1–57231–996–8).

Джеффри Рихтер, Кристоф Назар. Windows via C&C++. Программирование на языке Visual C++ – 5-е изд. – Питер, 2009 – 896 с., ISBN 978–5–388–00205–1, 978–5–7502–0367–3, 978–0–7356–2424–5 (англ.: 978–0735624245).

Павел Йосифович. Работа с ядром Windows. – Питер, 2021 – 400 c., ISBN 978–5–4461–1680–5 (англ.: 978-1977593375).

Pavel Yosifovich. Windows 10 System Programming, Part 1 – 2020, ISBN 979-8634170381 [англ].

Михаил Гук. Аппаратные средства IBM PC. Энциклопедия. – 3-е изд. – Питер, 2008. – 1072 с., ISBN 978–5–46901–182–8 (2001 г. – 816 с., ISBN 5–88782–290–2).

Владимир Кулаков. Программирование на аппаратном уровне. Специальный справочник (+ дискета). – 2-е изд. – Питер, 2003. – 848 с., ISBN 5–94723–487–4.

Всеволод Несвижский. Программирование аппаратных средств в Windows (+ CD-ROM). – 2-е изд. – БХВ-Петербург, 2008. – 528 с., ISBN 978–5–9775–0263–4.

Компиляторы и инструменты:

MASM32 (Macro Assembler) – наверное, самый популярный пакет самого популярного ассемблера.
MASM64 includes and libs – заголовки и библиотеки для 64-битной версии MASM (информация); файлы ml64.exe, link.exe и прочие потроха можно взять из Visual Studio (путь к папке с нужными файлами примерно такой: C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.12.25827\bin\Hostx64\x64\).

fasm (flat assembler) – современный и удобный компилятор под DOS, Wndows, Linux с очень развитой системой макросов и полным набором инструкций Intel/AMD. Рекомендую в качестве основного!
Там же можно скачать и fasmg (flat assembler g) – универсальный ассемблер под любую платформу (имеются include-модули для создания кода под AVR, i8051, x86/x64, генерации байт-кода JVM, аналогично можно создать свои модули).

NASM (Netwide Assembler) – ещё один современный кроссплатформенный компилятор с хорошей макросистемой и полным набором инструкций Intel/AMD, популярен в зарубежных проектах и при программировании под Linux/BSD.
NASMX – пакет макросов, include’ов, примеров и утилит для NASM под Windows, Linux, BSD, Xbox; включает макрос invoke, символы для работы с OpenGL и пр.

UASM (он же HJWasm) – современный MASM-совместимый мультиплатформенный ассемблер с полным набором инструкций Intel/AMD.

TASM 5.x (Turbo Assembler) – старый, но всё ещё популярный ассемблер, в основном используется для создания программ под DOS.

ALINK, GoLink – компоновщики для программ под DOS и Windows.

objconv – преобразователь форматов объектных файлов (COFF/OMF/ELF/Mach-O).

ResEd – бесплатный редактор ресурсов.

GoRC – компилятор ресурсов (rc → res) [в вышеупомянутом NASMX есть и GoLink, и objconv, и GoRC].

Windows 10 Software Development Kit (SDK) – заголовочные файлы, библиотеки, инструменты (в том числе отладчик WinDbg) для разработчиков Windows.

Fresh IDE – визуальная среда разработки для fasm.

SASM – простая кроссплатформенная среда разработки для NASM, MASM, GAS, fasm с подсветкой синтаксиса и отладчиком (для NASM имеется набор макросов для упрощения работы с консолью).

OllyDbg – популярный 32-битный отладчик (готовится 64-битная версия, но пока ещё не вышла).

x64dbg – хороший отладчик для 32- и 64-битного кода.

IDA Pro – мощный интерактивный дизассемблер (shareware).

VMware Workstation Player – мощный виртуализатор, позволяющий создавать и запускать виртуальные машины (бесплатный для персонального использования).

Oracle VirtualBox – альтернативный бесплатный виртуализатор.

Bochs – эмулятор компьютера IBM PC.

QEMU – эмулятор аппаратного обеспечения различных платформ (QEMU Manager).

Intel Software Development Emulator (SDE) – эмулятор расширений (инструкций) процессоров Intel.

DOSBox – очень популярный эмулятор компьютера для запуска программ под DOS (имеет встроенный замедлитель скорости).

Hiew – редактор двоичных файлов со встроенным дизассемблером, просмотром и редактированием заголовков исполняемых файлов (shareware).

PE Explorer – редактор секций, ресурсов PE, дизассемблер (shareware).

Windows Sysinternals – набор системных утилит для Windows (работа с процессами, мониторы и прочее).

ReactOS – бесплатная Windows-совместимая операционная система с открытым исходным кодом.

KolibriOS – миниатюрная ОС, умещающаяся на дискету 1.44 Mb, с исходниками на fasm.

Все эти ссылки (а также множество других, которые не вошли в эту статью) вы можете найти, кликнув сюда.

Также хочу пригласить вас в наш уютный «ламповый» раздел Assembler Форума на Исходниках.Ру 😉

Кто интересуется демосценой и сайзкодингом, welcome here.

Источник

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

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