Для чего нужен ассемблер: Погружение в ассемблер. Зачем учить ассемблер в 2020 году — «Хакер»

Содержание

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

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

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

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

 

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

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

  • ра­зоб­рать­ся, как работа­ют компь­ютер­ные прог­раммы. Разоб­рать­ся в деталях, на всех уров­нях, вплоть до машин­ного кода;
  • раз­рабаты­вать прог­раммы для мик­роско­пичес­ких встра­иваемых сис­тем. Нап­ример, для 4-бит­ных мик­рокон­трол­леров;
  • по­нять, что находит­ся под капотом у язы­ков высоко­го уров­ня;
  • соз­дать свой собс­твен­ный ком­пилятор, опти­миза­тор, сре­ду исполне­ния JIT, вир­туаль­ную машину или что‑то в этом роде;
  • ло­мать, отла­живать или защищать компь­ютер­ные сис­темы на самом низ­ком уров­не. Мно­гие изъ­яны безопас­ности про­явля­ются толь­ко на уров­не машин­ного кода и могут быть устра­нены толь­ко с это­го уров­ня.

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

 

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

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

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

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

  • Те дан­ные, к которым ты сей­час обра­щаешь­ся, заг­ружены в кеш или нет? А сама ком­бинация ассем­блер­ных инс­трук­ций?
  • Ес­ли ни дан­ные, ни код не раз­мещены в кеше, то не перетас­кива­ет ли их про­цес­сор туда вти­хомол­ку, пред­полагая, что к ним будут обра­щать­ся в бли­жай­шее вре­мя?
  • Ка­кие инс­трук­ции были выпол­нены непос­редс­твен­но перед нашим десят­ком? Они сей­час все еще на кон­вей­ере?
  • Мы слу­чаем не дос­тигли кон­ца текущей стра­ницы вир­туаль­ной памяти? А то, не дай бог, доб­рая полови­на нашего десят­ка попадет на новую стра­ницу, которая к тому же сей­час, по закону под­лости, вытес­нена на диск.
    Но если нам повез­ло и новая стра­ница таки в физичес­кой памяти, можем ли мы доб­рать­ся до нее через TLB-буфер? Или нам при­дет­ся про­дирать­ся к ней через пол­ный адрес, исполь­зуя таб­лицы стра­ниц? И все ли нуж­ные нам таб­лицы стра­ниц заг­ружены в физичес­кую память? Или какие‑то из них вытес­нены на диск?
  • Ка­кой имен­но про­цес­сор выпол­няет код? Дешевень­кий i3 или мощ­ный i7? Быва­ет, что у дешевых про­цес­соров тот же набор инс­трук­ций, что и у мощ­ных, но прод­винутые инс­трук­ции выпол­няют­ся в нес­коль­ко шагов, а не за один.

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

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

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

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

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

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

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

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

Ког­да ты пишешь на С что‑то вро­де x = a*2 + b*3, то естес­твен­ным обра­зом ожи­даешь уви­деть в ассем­бле­ре инс­трук­цию, которая умно­жает перемен­ную a на двой­ку. Но ком­пилятор зна­ет, что сло­жение дешев­ле умно­жения. Поэто­му он не умно­жает a на двой­ку, а скла­дыва­ет ее с самой собой.

Боль­ше того, гля­дя на b, ком­пилятор может счесть, что b + b + b пред­почти­тель­нее, чем b*3. Иног­да трой­ное сло­жение быс­трее умно­жения, иног­да нет. А иног­да ком­пилятор при­ходит к выводу, что вмес­то исходно­го выраже­ния быс­трее будет вычис­лить

(a + b)*2 + b. Или даже ((a + b)<<1) + b.

А если x исполь­зует­ся лишь однократ­но — при­чем в связ­ке с парой строк пос­леду­юще­го кода, — ком­пилятор может вооб­ще не вычис­лять x, а прос­то вста­вить a*2 + b*3 вмес­то икса. Но даже если x исполь­зует­ся и ком­пилятор видит что‑то вро­де y = x b*3, он может испра­вить эти рас­четы на y = a + a, удив­ляясь тво­ей рас­точитель­нос­ти. Рас­точитель­нос­ти в пла­не вычис­литель­ной слож­ности.

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

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

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

 

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

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

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

stdin сайт получал зап­рос, а через stdout отправ­лял резуль­тат в бра­узер. Ты можешь лег­ко реали­зовать тот же прин­цип на ассем­бле­ре.

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

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

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

От редакции

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

  • На­до учить Python или Lua, что­бы момен­таль­но получать резуль­таты. Это мотиви­рует!
  • На­до учить Scheme или Haskell из тех же сооб­ражений, что в шко­ле учат алгебру, а не, к при­меру, авто­меха­нику.
  • На­до учить Go для того же, для чего C, но в 2020 году.
  • На­до учить JavaScript и React.js, что­бы как мож­но быс­трее най­ти работу.
  • На­до учить Java, что­бы мак­симизи­ровать зарабо­ток.
  • На­до учить Swift, потому что почему нет?
  • На­до учить HolyC, что­бы сла­вить Гос­пода.
  • На­до учить Perl во имя Сатаны.

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

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

 

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

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

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

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

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

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

 

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

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

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

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

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

 

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

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

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

Чем же ассем­блер отли­чает­ся от язы­ков высоко­го уров­ня? Перемен­ные в нем — это прос­то области памяти. Здесь нет ни int, ни char. Здесь нет мас­сивов!

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

В ассем­бле­ре нет do..until, нет for..next, нет if..then. Вмес­то них там есть толь­ко опе­рации срав­нения и условно­го перехо­да. Стро­го говоря, там даже фун­кций нет.

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

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

 

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

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

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

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

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

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

Что такое Ассемблер?Зачем он вообще нужен?Что мы будем изучать?

Я думаю вам известо что PC не понимает слов,предложений и т. п.Всё что понятно этой замечательной машине — это наборы единиц и нолей(пример:0110 ).Зато люди двоичную систему не сильно любят(за исключением некоторых странных личностей).Поэтому когда первым програмистам надоело писать программы в двоичных кодах и вводить при помощи перфорированых карт они быстро замутили hex(шестнадцатиричный) редактор(пример простой  дос программы выводящей сообщение: b409ba0901cd21cd2048656c6c6f20776f726c642124).
Написать программу стало легче,но мастера древности решили что этого мало и изобрели Ассемблер.Теперь команды процессора можно было записать на понятном людям языке(каждой дали название.пример простой  дос программы выводящей сообщение:

; fasm example of writing 16-bit COM program

        org     100h    ;код стартует со смещения 100h
        use16           ;используем 16-битный код


;Вывод текста = 9

 mov     ah,9;Помещаем в регистр ah значение Вывод текста
 mov     dx,hello;Помещаем в dx адресс нащего текста
 int     21h ;Вызываем 21 прерывание
 int     20h ;Вызываем 21 прерывание-Выходим из программы

hello db ‘Hello world!’,24h;текст  нашего  сообщения )

. Вот тот же пример на C++:

#include <iostream.h>
int main()
{
   
cout << «Hello World!\n» ;
    return 0;
}

Затем стали появлятся новые языки. Они развивались,приобретали популярность и умирали забытые всеми,а Ассемблер сколько не пытались похоронить,каждый раз выживал . В чём его секрет?Зачем он вообще нужен?

Вроде бы есть столько языков-зачем нам нужен этот Ассемблер?Я думаю так думает основная масса тех кто собрался учить новый язык.И начинают учить C,С++,Delphi и т.д.То что «легче».На самом деле лёгкого языка.Что привлекает людей в C,C++?Это масса халявы.Вам тут и куча библиотек где за вас уже накатали 80 процентов программы,и гора справочных материалов,и примеры в изобилии.Тебе поручили создать какуюто прогу-нет проблем.Порылся на свалках исходников,кое-что переделал под себя(попросту испортил) и вот он наш шедевр,бежим за заслуженым гонорором(или отметкой если вы студент).
Однако задумайтесь вот над чем. Те кто пользуется FreeBSD знают что загрузчик(та фича с которой начинается загрузка ОС) этой замечательной ОС помещается в загрузочном секторе(это крохотные 512 байт).Как вы думаете  на чём он написан?Конечно на C!Ведь все UNIX’оиды пишутся на C.-Скажете вы.И сильно ошибётесь.Такой маленький загрузчик может быть написан только на Ассемблере.Вот реальный пример:

1.Программа на Fasm написаная под DOS(*.COM)

 22 байт

2. Программа на Fasm написаная под DOS(*.EXE)

59 байт

3.Программа на С++ написаная под DOS(*.EXE)

23 160 байт

Кстати C не намного лучще. Если вы хотите получить маленькую и шуструю программу-вам необходим Ассемблер.Вот для чего он используется:

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

Между прочем уже есть Операционные системы полностью написаные на Ассемблере(MenuetOS,SolarOS,Miraculix и др.).Они быстро развиваются и в будущем продемонстрируют миру на что способен Ассемблер.Кроме того программ написаных на Ассемблере стаёт больше с каждым днём.Появились среды разработки(IDE),библиотеки для облегчения написания программ,Сайты посвященные написанию программ на Asm в различных ОС(Windows,DOS,Linux,FreeBsd и др.)Если вы хотите написать первокласную программу,операционную сиситему,драйвер,антивирус,классный вирус,кряк,патч,или keygen вам Ассемблер необходим(но и про С/C++ не забывайте).
Я думаю с этим ясно,переходим к тому что нам будет нужно для изучения этого великого и могучего богатыря.

Я думаю не секрет что  новичок всегда хочет  получить программу не затрачивая больших усилий. Поэтому мы будем изучать Win32 програмирование на Fasm.
В ближайщее время мы узнаем:
1.Как вывести MessageBox.Стили MessageBox.
2.Создаём  обыкновенное окно.(прога будет иметь свою иконку).
3.Создаём диалоговое окно.
5.Выводим надпись(используя нужный нам шрифт).
4.Выводим картинку(используя BitBlt,StrechBlt и TransparentBlt).
5.Получаем время и выводим его на окно.
6.Проигрываем MP3,WAV,MIDI файлы.
7.Создаём непрямоугольные окна.
Пока я не решил что будем изучать дальше,но в скором времени определюсь и
с этим. Ещё я научу вас писать программы отображающие XP стили.

fasm — Ассемблер. Стоит ли его изучать теперь?

Закрыт 6 лет назад.

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

Я студент 2-го курса. Программирование мы начинали изучать сразу же с языка C, сейчас заканчивается курс ООП С++ (я не говорю про вспомогательные предметы типа основ конструирования программ и так далее). Мне нравится программировать, но меня никогда не покидала мысль: может стоит сначала разобраться в Ассемблере? Хочу конечно же когда-нибудь стать профессионалом и, разумеется, работать по специальности. Но хочется спросить: уместно ли изучение Ассемблера? Просто я ожидаю, что, изучив его, я больше буду понимать «внутреннюю реализацию». Но тут опять же вопрос: так ли важно это понимание, что внутри происходит? Я не знаю, понадобиться ли мне он на будущей работе, так как я, вероятнее всего, буду работать с языками высокого уровня. Может быть я смогу писать более оптимизированные программы. Но смогу ли так много выиграть за счет этого? Да и вообще сейчас особо с ресурсами проблем нет. А если еще подумать про читаемость кода… Думаю, она резко уменьшится, если я буду пользоваться Ассемблерными вставками (хотя я не уверен, что они используются для опитимизации :D). А может она мне в отладке поможет? Печально, что пока в универе на это внимание почти не уделяется, но я думаю, что это важно, особенно на следующих этапах, когда программы станут серьезными.

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

Заранее спасибо 😉

Зачем нам вообще нужен ассемблер, когда у нас есть компилятор?

Связанный: всегда ли компилятор создает код assembly? — подробнее о том, почему некоторые компиляторы компилируются только в asm, а не прямо в машинный код в каком-то формате объектного файла. Существует несколько причин, по которым компиляция в asm вместо машинного кода облегчает работу компилятора и делает его более легко переносимым. Но компиляторы-не единственная причина существования asm.

зачем нам вообще нужен ассемблер?

Многим людям не нужно знать язык assembly.

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

Компиляторы должны быть написаны людьми . Как указывает @old_timer , при разработке новой архитектуры CPU вы всегда даете имена опкодам и регистрам, чтобы можно было говорить о дизайне с другими людьми и публиковать читаемые руководства.

Или для разработки OS некоторые специальные привилегированные инструкции не могут быть сгенерированы компиляторами 1 . И вы не можете написать функцию переключения контекста, которая сохраняет регистры в чистом C.

CPUs запускает машинный код, а не языки высокого уровня напрямую, поэтому компьютерная безопасность / эксплойты и любой серьезный низкоуровневый анализ производительности / настройка одиночных циклов требуют просмотра инструкций, выполняемых CPU . Мнемонические названия для опкодов очень полезны при размышлении и написании о них. mov r32, imm32 гораздо легче запомнить и более выразителен, чем B8+rd imm32 (диапазон опкодов для этой мнемоники).

Сноска 1: Если только вы не создадите встроенные функции для всех специальных инструкций, таких как __invlpg() , которые должны использовать OSes, поэтому вы можете написать OS без встроенного asm. (Им все еще нужен какой-то автономный asm для таких вещей, как точки входа, и, вероятно, для функции переключения контекста.) Но тогда эти внутренние функции все еще нуждаются в именах в C, так что вы можете также назвать их в asm.


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

См . http://agner.org/optimize/ и другие ссылки на производительность в теге x86 wiki .

например, смотрите, может ли x86’s MOV действительно быть «free»?, почему can’t я вообще воспроизвожу это? а также режимы микро-слияния и адресации для примеров микро-бенчмаркинга, чтобы узнать что-то о том, что быстро.

Смотрите код C++ для проверки гипотезы Коллатца быстрее, чем написанный от руки assembly- почему? для получения дополнительной информации о написании asm вручную это быстрее, чем то, что я мог бы вручную удерживать gcc или _51 в излучении, даже настроив источник C так, чтобы он больше походил на asm, который я придумал.

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

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


Stack Overflow имеет несколько вопросов, таких как «what’s быстрее: a++ или ++a ?», и ответ полностью зависит от того, как именно он компилируется в asm, а не от синтаксических различий на уровне исходного кода. Чтобы понять, почему некоторые виды различий в источниках влияют на производительность, необходимо понять, как код компилируется в asm.

например, добавление избыточного назначения ускоряет код при компиляции без оптимизации . (Люди часто не понимают, что компиляция с/без оптимизации-это не просто линейное ускорение, и что в принципе бессмысленно тестировать неоптимизированный код. Неоптимизированный код имеет различные узкие места… Это очевидно, если вы посмотрите на asm.)

Ассемблер для Windows

Предисловие автора

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

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

Что касается операционной системы Windows1, то здесь, как ни странно это прозвучит для уха некоторых программистов, программировать на ассемблере гораздо легче, чем в операционной системе MS DOS. В данной книге я берусь доказать, что программировать на ассемблере в Windows ничуть не сложнее чем на Си, и при этом получается компактный, эффективный и быстрый код. Работая с языками высокого уровня, мы теряем определенные алгоритмические навыки. И процесс заходит все дальше. Честное слово, только ради повышения своего профессионального уровня стоит заниматься программированием на ассемблере.

Как и предыдущая, эта книга будет содержать только работающие программы с подробным разбором и комментарием.

Сейчас существует два основных конкурирующих ассемблера MASM (Macro Assembler) и TASM (Turbo Assembler)2. Для всех программ будет оговорено, как транслировать их с помощью и MASM, и TASM.

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

Надо сказать, что в литературе по программированию для Windows 9Х образовалась некоторая брешь — авторы очень быстро перешли от чистого API-программирования 3 к описанию визуальных компонент тех или иных языков. Автору известна лишь одна, да и то переводная, книга по «чистому» программированию для Windows: Герберт Шилдт, Программирование на С и C++ для Windows 954 (см. также [12]). В своей книге я пытаюсь прикрыть эту брешь, рассматривая некоторые малоосвещенные в литературе вопросы: программирование в локальной сети, использование многозадачности, написание VXD-драйверов, обработка файлов и др.

Обычно книги по программированию тяготеют к одной из двух крайностей: описание языка программирования, описание средств программирования операционной системы. Мне хотелось удержаться посередине. Данная книга не руководство по языку ассемблера и не руководство по программированию в Windows. Это нечто среднее, можно сказать — симбиоз языка ассемблера и операционной системы Windows. Как я справился с данной задачей — судить Вам, дорогой читатель.

весит 2,18 МБ скачать

Как в действительности исполняются наши программы? (Ассемблер и его друзья)

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

Современные языки высокого уровня (такие, как python, JavaScript, C#) в ходе своего развития стремятся приблизится к естественным языкам (в подавляющем большинстве случаев, английскому). В их синтаксисе появляются более абстрактные конструкции (классы, объекты, замыкания).

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

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

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

Язык программирования, который наиболее близок к языку команд процессора – язык Ассемблера. (Ассемблер – это не язык сам по себе, это программа, переводящая инструкции языка Ассемблера в язык машинных команд).

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

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

Читайте мою книгу «Ассемблер на пальцах», в которой я подробно и наглядно разбираю основные концепции языка ассемблера и принципы работы процессора Intel x86 в реальном режиме работы.

Репетиторы по Assembler в Москве — 2841 репетитор, 29 отзывов на Профи

Мой сын более двух лет занимался с разными репетиторами по программированию (перепробовали около 30 разных репетиторов), но тем не менее ребёнок чувствовал себя не очень неуверенно, в голове была «каша», пока не попали к Максиму Юрьевичу. Мой вам совет, не выбрасывайте деньги на ветер, поверьте… Читать дальше

это бесполезно. Даже основы программирования лучше сразу получать у грамотного специалиста, иначе вам придётся тратить ещё и ещё больше, для того чтобы потом правильно переучивать ребёнка, а это намного сложнее и для вас и для него. Единственное о чем мы жалеем, что потратили два года на других репетиторов почти впустую. Если бы мы сразу попали к Максиму Юрьевичу, то уже сейчас могли бы как минимум не только участвовать в олимпиадном программировании среди студентов, но и спокойно и достойно побеждать. Максим Юрьевич не только преподаватель от бога, но и очень талантливый программист! Не было ни одной задачи, которую он не смог бы объяснить, разложив её буквально «по полочкам» и при этом ещё и систематизируя нашу «кашу» и попутно изучая с ребенком разные способы решения. При разработке программы надо учитывать её структуру и очень часто просто необходимо применять разные типы решения, а большинство задач были очень сложные, даже опытные преподаватели вузов отказывали нам в помощи при их решении. Это единственный репетитор, который не только систематизирует знания по языку программирования, но и учит правильно выстраивать архитектуру большой программы, грамотно оптимизировать код, пользоваться отладчиком и т.д.(до него этому не учил НИКТО). Многие репетиторы давали домашнее задание по пройдённой теме, но тем не менее сын очень часто говорил, что самостоятельно не может их сделать или не понимает как их делать. Это происходит потому, что у самих репетиторов нет системы и понимания, многие темы они сами делают настолько сложно и запутанно, что любая система волей-неволей превращается в хаос. У Максима Юрьевича происходит с точностью до наоборот. Ребёнок не только самостоятельно выполняет домашнее задание, но и делает это с огромным удовольствием и интересом. И это не одна-две задачи, как у других, а минимум 10-15. Кроме профессиональных, очень хочется отметить и великолепные личные качества Максима Юрьевича: чуткость, душевную теплоту, понимание, доброту, внимательность. Поверьте, для него важен каждый ребёнок, с которым он занимается. Несмотря на бешённую загрузку, он всегда находит время для каждого. За этот год ни разу не было момента, когда бы он нас подвёл или не откликнулся на наш дополнительный, но несвоевременный вопрос вне часов занятий. Очень рекомендую всем Максима Юрьевича, хотя он нам самим очень и очень нужен!!!

Что такое ассемблер? — Определение с сайта WhatIs.com

От

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

Вот как это работает:

  • Большинство компьютеров поставляются с определенным набором самых простых инструкций, которые соответствуют основным операциям, которые компьютер может выполнять.Например, команда «Загрузить» заставляет процессор перемещать строку битов из места в памяти процессора в специальное место хранения, называемое регистром. Предполагая, что процессор имеет не менее восьми регистров, каждый из которых пронумерован, следующая инструкция переместит значение (последовательность битов определенной длины) из ячейки памяти 3000 в место хранения, называемое регистром 8:
     L 8,3000 
  • Программист может написать программу, используя последовательность этих инструкций ассемблера.
  • Эта последовательность инструкций ассемблера, известная как исходный код или исходная программа, затем указывается программе ассемблера при запуске этой программы.
  • Программа на ассемблере принимает каждый оператор программы в исходной программе и генерирует соответствующий битовый поток или шаблон (последовательность нулей и единиц заданной длины).
  • Выходные данные программы ассемблера называются объектным кодом или объектной программой относительно исходной программы ввода. Последовательность нулей и единиц, которые составляют объектную программу, иногда называют машинным кодом.
  • После этого объектную программу можно запустить (или выполнить) в любое время.

На самых ранних компьютерах программисты фактически писали программы в машинном коде, но вскоре были разработаны языки ассемблера или наборы инструкций для ускорения программирования. Сегодня программирование на ассемблере используется только там, где требуется очень эффективный контроль над операциями процессора. Однако для этого требуется знание набора команд конкретного компьютера. Исторически сложилось так, что большинство программ было написано на языках «более высокого уровня», таких как COBOL, FORTRAN, PL / I и C. Эти языки легче изучать и быстрее писать программы, чем язык ассемблера. Программа, обрабатывающая исходный код, написанный на этих языках, называется компилятором. Как и ассемблер, компилятор принимает операторы языка более высокого уровня и сводит их к машинному коду.

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

Последний раз обновлялся в ноябре 2005 г.

Продолжить чтение об ассемблере
Узнайте подробнее о стратегии серверного оборудования

Определение ассемблера Merriam-Webster

как · сем · блер | \ ə-ˈsem-b (ə-) lər \ 2а : компьютерная программа, которая автоматически преобразует инструкции, написанные на ассемблере, в машинный язык.

Введение в Ассемблер — GeeksforGeeks

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

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

  • Pass-1:
    1. Определите символы и литералы и запомните их в таблице символов и таблице литералов соответственно.
    2. Отслеживание счетчика местоположения
    3. Обработка псевдоопераций
  • Pass-2:
    1. Создание объектного кода путем преобразования символьного кода операции в соответствующий числовой код операции
    2. Создание данных для литералов и поиск значений символов

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

 [Метка] [Код операции] [операнд]

  Пример:  M ADD R1, = '3'
где, M - метка; ADD - символический код операции;
R1 - операнд символьного регистра; (= '3') - буквальный

  Программа сборки: 
Метка Операционный код операнда значение LC (счетчик местоположения)
ДЖОН СТАРТ 200
       MOVER R1, = '3' 200
       MOVEM R1, X 201
L1 ДВИГАТЕЛЬ R2, = '2' 202
       LTORG 203
Х ДС 1 204
       КОНЕЦ 205
 

Давайте посмотрим, как работает эта программа:



  1. START: Эта инструкция запускает выполнение программы с позиции 200, а метка с START дает имя программе.(JOHN — имя программы)
  2. MOVER: Перемещает содержимое литерала (= ’3 ′) в регистровый операнд R1.
  3. MOVEM: Перемещает содержимое регистра в операнд памяти (X).
  4. MOVER: Он снова перемещает содержимое литерала (= ’2 ′) в регистровый операнд R2, а его метка указывается как L1.
  5. LTORG: Назначает адрес литералам (текущее значение LC).
  6. DS (пространство данных): Он назначает пространство данных 1 символу X.
  7. END: Завершает выполнение программы.

Работа Pass-1: Определите символьную и буквальную таблицу с их адресами.
Примечание: буквальный адрес указывается как LTORG или END.

Шаг 1: START 200 (здесь нет символа или литерала, поэтому обе таблицы будут пустыми)

Шаг 2: MOVER R1, = ‘3 ′ 200 (=’ 3 ‘- литерал, поэтому буквенная таблица)

Литерал Адрес
= ‘3’ — — —

Шаг 3: MOVEM R1, X 201 символ X упоминается до его объявления, поэтому он сохраняется в таблице символов с пустым полем адреса.

Символ Адрес
X — — —

Step-4: L1 MOVER R2, = ‘2 ′ 202
L1 — это метка 2 ‘является буквальным, поэтому сохраните их в соответствующих таблицах

901 901 901
Символ Адрес
X — — —
L1 202
Адрес
= ‘3 ′ — — —
=’ 2 ′ — — —

Шаг 5: LTORG 203
Назначить адрес первому буквенному по значению LC, т. е.e., 203

Буквальный Адрес
= ‘3’ 203
= ‘2’ — — —
Шаг DS 1 204
Это оператор объявления данных, т.е. X назначается пространство данных 1. Но X — это символ, который упоминался ранее на шаге 3 и определен на шаге 6. Это состояние называется проблемой прямой ссылки, где переменная упоминается ранее. к его декларации и может быть решен путем обратного исправления.Итак, теперь ассемблер назначит X адрес, указанный значением LC текущего шага.

Шаг 7: END 205
Программа завершает выполнение, и оставшийся литерал получит адрес, указанный значением LC инструкции END. Вот полная таблица символов и букв, составленная на первом этапе ассемблера.

Литерал Адрес
= ‘3’ 203
= ‘2’ 205
передаст

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

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

Различные Базы данных, необходимые для Pass-2:

1. Таблица MOT (таблица кодов операций станка)
2.Таблица POT (таблица псевдо-кодов операций)
3. Базовая таблица (хранящая значение базового регистра)
4. LC (счетчик местоположения)
 

Взгляните на блок-схему, чтобы понять:

В целом ассемблер работает как:

Языковые процессоры: Ассемблер, компилятор и интерпретатор

Языковые процессоры: Ассемблер, компилятор и интерпретатор

Языковые процессоры —
Язык ассемблера зависит от машины, но мнемоника, которая используется для представления инструкций в нем, не может быть непосредственно понятна машиной, а язык высокого уровня не зависит от машины. Компьютер понимает инструкции в машинном коде, то есть в форме нулей и единиц. Написание компьютерной программы непосредственно в машинном коде — утомительная задача. Программы написаны в основном на языках высокого уровня, таких как Java, C ++, Python и т. Д., И называются исходным кодом . Этот исходный код не может быть выполнен непосредственно компьютером и должен быть преобразован в машинный язык для выполнения. Следовательно, для перевода программы, написанной на языке высокого уровня в машинный код, используется специальное программное обеспечение системы трансляции, которое называется Language Processor , а программа после преобразования в машинный код (объектная программа / объектный код).

Языковые процессоры могут быть любого из следующих трех типов:

  1. Компилятор —
    Языковой процессор, который за один раз считывает полную исходную программу, написанную на языке высокого уровня, и переводит ее в эквивалентную программу на машинный язык называется компилятором.
    Пример: C, C ++, C #, Java

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



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

  3. Интерпретатор —
    Перевод отдельного оператора исходной программы в машинный код выполняется языковым процессором и выполняет его непосредственно перед переходом к следующей строке и называется интерпретатором.Если в операторе есть ошибка, интерпретатор завершает процесс перевода на этом операторе и отображает сообщение об ошибке. Интерпретатор переходит к следующей строке для выполнения только после устранения ошибки. Интерпретатор напрямую выполняет инструкции, написанные на языке программирования или сценариях, без предварительного преобразования их в объектный код или машинный код.
    Пример: Perl, Python и Matlab.

Разница между компилятором и интерпретатором —

Интерпретатор
Компилятор Интерпретатор
Компилятор — это программа, которая охватывает весь исходный код языка программирования в исполняемый машинный код для ЦП. берет исходную программу и запускает ее построчно, переводя каждую строку по мере ее поступления.
Компилятору требуется много времени для анализа всего исходного кода, но общее время выполнения программы сравнительно меньше. Интерпретатору требуется меньше времени для анализа исходного кода, но общее время выполнения программы меньше.
Компилятор генерирует сообщение об ошибке только после сканирования всей программы, поэтому отладка сравнительно сложна, поскольку ошибка может присутствовать в любом месте программы. Его отладка упрощается, поскольку он продолжает транслировать программу до тех пор, пока не будет обнаружена ошибка.
Создает промежуточный объектный код. Промежуточный объектный код не создается.
Примеры: C, C ++, Java Примеры: Python, Perl

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

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

Язык ассемблера (или Ассемблер) скомпилирован , компьютерный язык низкого уровня.Он зависит от процессора, поскольку в основном переводит мнемонику Ассемблера непосредственно в команды, понятные конкретному процессору, на взаимно однозначной основе. Эти мнемоники ассемблера представляют собой набор инструкций для этого процессора. Кроме того, Ассемблер предоставляет команды, которые управляют процессом сборки, обрабатывают инициализацию и позволяют использовать переменные и метки, а также управлять выводом.

На ПК Ассемблер обычно используется только под MS-DOS. При работе в 32-битной операционной системе с защищенным режимом (включая Windows 95 / NT и выше) низкоуровневые программы, которые напрямую обращаются к регистрам или ячейкам памяти, вызывают нарушения защиты.Весь низкоуровневый доступ должен осуществляться через соответствующие драйверы программного обеспечения.

Для ПК с MS-DOS самым популярным языком ассемблера был Microsoft Macro Assembler или MASM. Как и большинство популярных компиляторов, MASM регулярно обновлялся. Большая часть этого обсуждения относится к версии 5.0 или более поздней, которая упростила использование определенных директив и включила поддержку инструкций, доступных только на процессорах 80286 и 80386.

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

Одна из важных директив MASM — это .MODEL, которая определяет максимальный размер программы. Помните, что для ЦП семейства 80 × 86 память адресуется как сегменты длиной до 64 Кбайт.Если используется 16-битная адресация (для кода или данных), будет доступен только один сегмент размером 64 КБ. Модель памяти программы определяет, как различные части этой программы (код и данные) обращаются к сегментам памяти. MASM поддерживает пять моделей памяти для программ DOS: Small, Medium, Compact, Large и Huge. В модели Small все данные помещаются в один сегмент размером 64 КБ, а весь код (исполняемые инструкции) помещается в другой сегмент размером 64 КБ. В модели Medium все данные помещаются в один сегмент размером 64 КБ, но код может быть больше 64 КБ (многосегментный, требующий 32-разрядной адресации для сегмента: смещение).В модели Compact весь код помещается в один сегмент размером 64 КБ, но данные могут занимать более 64 КБ (но ни один массив не может быть больше 64 КБ). В большой модели и код, и данные могут быть больше 64 КБ (при этом ни один массив данных не может превышать 64 КБ). Наконец, в модели Huge размер кода и данных может превышать 64 КБ, а массивы данных также могут превышать 64 КБ.

Поскольку для более крупных моделей требуются более крупные адреса, они производят более крупные и медленные программы, чем модель меньшего размера. При выборе модели для программы постарайтесь оценить максимальный объем хранилища данных, который вам понадобится.Допустим, вы пишете программу БПФ, используя 16-битную целочисленную математику и максимальный размер выборки 2048 точек. Поскольку для каждой точки требуется два целых числа (действительное и мнимое), а каждое целое число имеет длину 2 байта, вам нужно 8096 байтов только для хранения входных (или выходных) данных. Даже если бы у вас были отдельные массивы для входных и выходных данных, это все равно было бы всего 16 192 байта. В качестве запаса прочности для временного хранилища мы удвоим это число до 32 384 байта, что составляет лишь половину сегмента размером 64 КБ. Размер кода оценить сложнее.В этом примере мы начнем с модели Small. Если бы размер кода оказался больше 64 КБ (что непросто сделать на языке ассемблера), мы бы перешли к модели Medium. Эти же модели памяти также применимы к компиляторам языка DOS высокого уровня от Microsoft. Если вы пишете программу MASM для работы с другим языком высокого уровня, вы должны использовать одну и ту же модель памяти для обоих.

Вот пример простой программы MASM, которая отображает на экране текстовую строку («Это простая программа MASM») с помощью функции DOS. 09h:

Здесь используются несколько директив.DOSSEG сообщает MASM о необходимости позаботиться о порядке различных сегментов (кода, данных, стека) — деталь, которую мы предпочли бы игнорировать. Директива .DATA указывает начало сегмента данных, а .CODE указывает начало сегмента кода. Сообщение обозначается меткой text, , где директива DB (Defines Bytes) указывает, что это байтовые данные (кавычки обозначают текст ASCII). Строка должна заканчиваться символом ASCII 24h («$») для функции DOS 09h. Исполняемые инструкции помещаются в сегмент кода.Ярлык « идти», «» указывает на начало программы. Адрес текстовой строки загружается в регистры DS: DX. Затем вызывается функция DOS 09h для отображения строки. Наконец, вызывается функция DOS 4Ch для выхода из программы и возврата в DOS. Последняя директива END указывает MASM начать выполнение программы с метки (адреса) go.

MASM называется Macro Assembler, потому что он поддерживает использование макросов. Макрос — это блок программных операторов, которому присвоено символическое имя, которое затем можно использовать в нормальном программном коде.Макрос также может принимать параметры, когда он вызывается в программе. Когда исходный файл собирается с помощью MASM, любые макросы расширяются (переводятся) в исходный текст определения. Это очень удобно, если один и тот же фрагмент кода, например, функция, определяемая программистом, используется повторно. Часто предопределенные макросы могут храниться в отдельном файле вместе с другой информацией, такой как инициализация переменных. Директива INCLUDE может читать этот файл во время сборки.

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

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

Раскрытие информации: Ваша поддержка помогает поддерживать работу сайта! Мы зарабатываем реферальный сбор за некоторые услуги, которые мы рекомендуем на этой странице.Узнать больше

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

Введение

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

  10110000 01100001  

Первые несколько битов ( 10110 ) представляют собой инструкцию для копирования значения в регистр. Следующие три цифры ( 000 ) определяют регистр, в который будет скопировано значение. Остальное ( 01100001 ) — это значение, которое нужно скопировать.

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

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

Пример

Например, если 10110 означает «переместить значение», то мы могли бы сократить его с помощью команды MOV .

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

Наконец, мы можем отобразить значение в другой системе счисления, например в десятичной ( 91 ) или шестнадцатеричной ( 61 ). Тогда эта строка будет MOV AL, 61 . Как только вся программа написана таким образом, ассемблер может легко преобразовать каждую строку в соответствующее двоичное представление.

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

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

Ресурсы языка ассемблера

Интернет-ресурсы

Учебники и базовые руководства
  • Учебник по программированию на ассемблере из пункта Учебники

  • Программирование на языке ассемблера X86, глава из Руководства разработчиков FreeBSD, которая помогает писать на ассемблере в контекст разработки операционной системы

  • Say Hello to X64 Assembly, довольно мягкое введение в сборку, из блога Code as Art

  • Программирование на языке ассемблера X86, еще одно руководство, в котором язык ассемблера хорошо помещается в контекст программирования ОС , это относится к Linux, Windows и даже немного к Mac OS X

  • Язык сборки ПК, это ориентировано на 32-разрядные ПК под управлением Linux, Windows или FreeBSD

  • Руководство по сборке X86, из Департамент компьютерных наук Университета Вирджинии

  • Webster: выставление счетов как » Место в Интернете для изучения ассемблера », этот сайт (по всей видимости) управляется автором The Art of Assembly Language и изобретателем HLA

  • Linux Assembly Tutorial

  • Easy X86-64

  • Сборка X86

  • Учебник по программированию на ассемблере Windows (pdf)

Видеоуроки
  • Учебник по программированию на языке ассемблера, очень подробная серия из 55 видео по сборке, следующая за книгой Assembly Language for x86 Процессоры (6-е издание) от Кипа Ирвина (если вы не следите за видео, вы, вероятно, захотите более новое издание)

  • Видеокурс по программированию на языке ассемблера, серия видео из 70 частей, преподаваемая Артуром Гриффитом , обладающий очень народным обаянием

  • Введение в язык ассемблера, лекция в классе в Корнелле, знакомящая с языком ассемблера

  • A ssembly Language Programming, часовое введение в ассемблер и отличный формат, если вам действительно нравилось следовать примерам алгебры на диапроекторе, когда вы учились в старшей школе (это часть большой серии статей о микропроцессорах и микроконтроллерах).

Ссылка
Инструменты

Ассемблеры — доступно множество ассемблеров — вот несколько из самых популярных бесплатных ассемблеров с открытым исходным кодом:

IDE (интегрированные среды разработки):

  • SASM, Simple кроссплатформенная IDE для языков ассемблера NASM, MASM, GAS, FASM

  • Свежая IDE, IDE на визуальном языке ассемблера со встроенным ассемблером FASM

  • WinAsm Studio, бесплатная IDE для разработки 32-битной Windows и 16-битной DOS программы на Ассемблере

  • Visual MASM.

Сообщество и постоянное обучение

Книги

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

Стоит ли вам изучать ассемблер, зависит от ваших целей. Для большинства разработчиков ответ — «нет».

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

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

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

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

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

Другие вещи для изучения

Есть некоторые языки, на которых, если вы немного знаете, вы можете многое. Таковы Python и Ruby — за выходные можно выучить достаточно, чтобы создать что-то стоящее. Ассемблер не такой.

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

  • Аппаратные языки, такие как VHDL и Verilog, а также хорошее понимание микропроцессоров и электротехники

  • Низкоуровневые языки операционных систем, такие как C и его производные: C ++, C # и D

  • Устаревшие языки, такие как Fortran и Cobol

  • Языки платформы, такие как Java и Objective-C

  • Алгоритмы

  • Компилятор, интерпретатор и языковая разработка.


Дополнительная литература и ресурсы

У нас есть лотов, дополнительной информации о таких вещах, Программирование: языки, временная шкала и руководства.

Какой код следует выучить?

Не знаете, на каком языке программирования вам следует научиться программировать? Ознакомьтесь с нашей инфографикой, Какой код вам следует выучить?

В нем не только обсуждаются различные аспекты языков, но и даются ответы на такие важные вопросы, как «Сколько денег я буду зарабатывать на программировании на Java?»

Что такое ассемблер с примером?

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

В следующем примере я буду использовать ассемблер Nasm для кода Intel и ассемблер Xa для кода 6502.

; вызов ассемблера «nasm»:; nasm -f elf64 hello_64.

Что такое ассемблер и его виды?

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

Что такое ассемблер простым языком?

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

Что такое компилятор и пример?

Компилятор — это программа, которая переводит исходную программу, написанную на каком-либо языке программирования высокого уровня (например, Java), в машинный код для некоторой компьютерной архитектуры (такой как архитектура Intel Pentium).

Оставить комментарий

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

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