Как создавались мнемоники Языка ассемблера из двоичных кодов?
Подскажите, где копать информацию, или, пожалуйста, объясните, как из команды, например, сложения на двоичном коде 0000 0100 создали мнемонику ADD ? Кажется чистой магией, что из тумблеров и дырок/отсутствия дырок на перфокарте создали вводимый на дисплее текст, который трансформируется в цифры.
Отслеживать
задан 9 сен 2020 в 14:55
Valit Laiho Valit Laiho
115 3 3 бронзовых знака
ADD это просто человекодружелюбное название/представление 00000100 в контексте команд.
9 сен 2020 в 14:58
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Изначально программисты писали программы в машинных кодах, составляя длинные последовательности из нулей и единиц. Машинные коды в буквальном смысле представляют высокие и низкие уровни напряжения на “ножках” микросхемы процессора. Внутренняя структура логических элементов микросхемы из которой образуются арифметико-логическое устройство и диктовала то, какие уровни должны были быть выставлены на управляющих пинах.
Программирование в машинных кодах было очень трудоёмким и порождало огромное количество ошибок, дебаг которых был адской задачей. Очень быстро стало понятно, что процесс поиска нужной машинной команды для определённого действия можно автоматизировать и в 50-х годах начали применять мнемонический язык ассемблер. Он позволил представлять машинные кода в более удобном для людей виде.
Для того чтобы не запоминать кучу машинных команд программисты используют транслятор который «подставляет» вместо мнемоник ADD определённые значения типа 0000 0100 . Грубо говоря как операция «Заменить» в текстовых редакторах.
Для более подробного понимания могу посоветовать книгу «Цифровая схемотехника и архитектура компьютера» Харрис Д.М.
Так же есть прекрасный курс “NAND2tetris” (на английском, бесплатный), который позволяет пройти все этапы проектирование своего микропроцессора от базовых логических операций до компьютерной игры, проходя все уровни абстракций.
Отслеживать
ответ дан 9 сен 2020 в 15:03
1,274 2 2 золотых знака 10 10 серебряных знаков 24 24 бронзовых знака
Правильно ли я понимаю, что используется кодировка ASCII для представления этих машинных команд в буквенных мнемониках, а транслятор же это мэппит в машинный код? За книгу огромное спасибо.
История некоторых языков программирования
Как известно компьютер воспринимает команды в двоичном коде, но программы на нем писали в основном до середины прошлого века. Намного упрощало создание программ использование языков программирования, именно о них и пойдет речь в данной статье.
Ada(Ада)
Язык Ada был разработан при поддержке Минобороны США в 1978 году в результате конкурса на котором выиграла группа программистов компании Honeywell. Назван по имени первой женщины программистки Ады Лавлейс. Конечная спецификация разработана к 1983 году. Вне военных проектов язык широкого распространения не получил.
Язык возник в результате международного конкурса языковых проектов. Он должен был удовлетворять всем требованиям министерства обороны США. Интересно, что все языки, дошедшие до последних туров этого конкурса, были основаны на Паскале. В этой связи Аду можно предварительно охарактеризовать как развитый Паскаль. Конечная спецификация разработана к 1983 году. Вне военных проектов язык широкого распространения не получил.
Assembler (Ассемблер)
Язык ассемблера люди начали использовать с 1950 года. Этот язык первым позволил отображать двоичный код в более удобной для человека форме: в виде букв или укороченных слов, которые примерно обозначали сущность команды. Умея разбираться в распечатке ассемблера, можно находить ошибки в программах созданных даже при помощи других языков. В данный момент у каждого из нас дома стоят много «интерпретаторов ассемблера» — менюшки в телевизорах, программы стиралок разработаны зачастую именно на нем. (хотя программисты-лентяи пишут программы для микроконтроллеров и на C). Кроме того, на ассемблере написаны драйверы устройств, библиотеки и функции программ, написанных даже на других языках.
Кроме того, на ассемблере создаются целые операционные системы, примером может стать Menuet OS.
Algol (Алгол)
ALGOrithmic Language, разработанный в 58-60 гг. прошлого столетия считается предком многих современных алгоритмических языков, т.к. именно в нем впервые осуществились основные идеи алгоритмизации. Именно в алголе стало относительно просто превращать алгебраические выражения в команды и вычитывать значения функций. В своё время алгол был популярен в прикладной физике и математике, но сейчас практически не используется.
Basic (Бейсик) и VBScript
Интерпретационный язык бейсик разработанный в 1960 году изначально предназначался именно для новичков, о чем свидетельствует даже его название — Beginner’s All-purpose Symbolic Instruction Code (многоцелевой символьный код для начинающих). Этот язык считается простейшим языком высокого уровня. Плохая поддержка процедурного программирования сделала его неподходящим для больших проектов, но зато способным создать небольшие программы за считанные минуты. Небольшой размер интерпретатора определил язык как встраиваемый во многие 8-разрядные ПЗП компьютеры и компьютеры прошлых поколений. (Автору статьи приходилось писать программы на таком Basic’е)
Включений версии Quick Basic в состав Ms-Dos проложило для него неплохую дорогу развития и сейчас его версии (Visual Basic, VBA…) являются одними из популярнейших сред для написания программ.
Основными проблемами программистов использующих VB является отсутствие нормальной справки (популярная, укороченная версия идет без MSDN) и необходимость «носить» за программой библиотеки, т.к. объекты, используемые в программах (кнопки, скроллы, метки…) требуют библиотек, которые есть не на всех компьютерах.
Именно Basic сделал программирования более доступным для большинства людей.
На бейсике часто пишут…вирусы, вирусы для Microsoft Office. Включение VBA (Visual Basic for Application) в офисный пакет предопределило написание на нем не только макросов, но и вирусняков.
Идея появления языка VBScript заключалась в представлении разработчикам Web- страниц возможности использования привычных команд VB наряду с тегами HTML, что позволило разрабатывать мощные и богатые страницы. VBScript загружается в виде ASCII-текста и не имеет прав работы с файловой системой клиента, таким образов полностью обезопасив пользователя.
Слабая поддержка браузерами этого языка, «способствует» его медленному развитию, а после выпуска VS2003, практически и смерти… (начиная с .NET Microsoft-овский Basic де-факто стал обёрткой, отличающейся от C# только синтаксисом, потеряв большинство своих преимуществ (например модификацию кода «на лету»))
Наверное не один язык не получил столько критики, сколько Basic.
Эдсгер Дейкстра, даже заявил что студентов изучивших бейсик, невозможно обучить хорошему программированию. Безусловно это является полнейшим бредом. Т.к. язык по сути является лишь средством, а качество программирования зависит от опыта создания программ и способа мышления.
C (Си)
Язык программирования Си был разработан в 1972 году Деннисом Ритчи, в компании Bell Laboratories. Название происходит от номера проекта лаборатории (“A”,”B”,C”…). Изначально этот язык задумывался как промежуточный между языками высокого и низкого уровней, но продуктивность и компактность кода + преимущества структурного языка, несмотря на сложность обучения сделали Си самым популярным языком.
В 1980 году компания выпускает новый язык построенный на основе С — С++. По словам разработчика, Бьярна Страуструпа он должен «укорить написание хороших программ и сделать этот процесс наиболее приятным для каждого отдельно взятого программиста». Название С++ было придумано вместо начального «C с классами».
В наше время этот язык наиболее популярен и универсален, что доказывает создание именно на ней всемирной ОСи — Windows.
Сейчас Си считается основой для разработки современных больших и сложных проектов. Конечно, как и у всего существующего в природе, у него имеются и слабые стороны, вытекающие из требований эффективности.
Помимо «Окон» на Си написаны такие известные программы как Outlook, Opera, 1C.
Cobol (Кобол)
«Общепринятый язык, ориентированный на бизнес», именно так расшифровывается название кобола (Common Business Oriented Language). Здесь появились способы обработки предвестников современных баз данных используемых на предприятиях и фирмах. Несмотря на свой довольно сложный синтаксис кобол довольно долго использовался в экономике и бизнесе, лишь недавно уступив место таким системам программирования БД как SQL и FoxPro.
Fortran (Фортран)
Фортран — самый первый компилированный язык программирования, базовые принципы и понятия которого легли в основу многих современных языков программирования высокого уровня. Разработанный в 1954-1958 гг Джимом Бекусом, он предназначенный для сложных научно-технических исследований, довольно быстро стал популярным среди инженеров и ученых и до сих пор используется, хотя уже и не в таких широких кругах. Название происходит от словосочетания «ТРАНслятор ФОРмул». Стандарты языка четко определенны, их всего четыре: fortran 66, fortran 77, fortran 90 и fortran 95
Фортран имеет множество математических функций, поддерживает работу с длинными числами. Благодаря использованию четких стандартов фортран иногда используют для переноса программы между платформами.
Фортран имеет достаточно большой набор встроенных математических функций, поддерживет работу с целыми, вещественными и комплексными числами высокой точности. Выразительные средства языка изначально были весьма бедны, поскольку Фортран был одним из первых языков высокого уровня. В дальнейшем в Фортран добавляли многие лексические конструкции, характерные для структурного, функционального и даже объектно-ориентированного программирования, однако они не были в достаточной мере востребованы, поскольку сейчас Фортран нужен в основном для переноса давно написанных программ с одной платформы на другую, а не для написания новых.
Java и JavaScript
Созданная компанией Sun Microsystems система разработки Java безопасна и высокопроизводительна. Java — объектно-ориентированный язык, удобный и надёжный в эксплуатации благодаря таким своим достоинствам, как многозадачность, поддержка протоколов Internet и многоплатформенность. Java — это интерпретируемый язык, и каждая Java-программа компилируется для гипотетической машины, называемой Виртуальная Машина Java. Результатом такой компиляции является байт-код Java, который в свою очередь может выполняться на любой операционной системе при условии наличия там системы времени выполнения Java, которая интерпретирует байт-код в реальный машинный код конкретной системы.
Язык Java является объектно-ориентированным и поставляется с достаточно объемной библиотекой классов. Библиотеки классов Java значительно упрощают разработку приложений, предоставляя в распоряжение программиста мощные средства решения распространенных задач.
На Java написан движок известного эмулятора «Ил-2: Штурмовик».
Для создания компилируемых апплетов компания Netscape разработала язык JavaScript, который был внедрен в всемирно известный браузер компании.Первоначальное название — LiveScript, которое позже изменилоь получив разрешение у компание Sun. Microsoft на создание ответило своим языком JScript, после чего многие создатели браузеров начали выпускать свои спецификации, что сделало задачу написания вездеработающего скрипта довольно сложной.
Pascal (Паскаль) и Delphi
Разработанный Никлаусом Виртом (а не французским математиком Блезом Паскалем, как абсолютно уверены половина людей J) в 1967-1971 годах компилированный язык программирования, изначально стал популярным в основном благодаря относительно простому синтаксису. Выпуск компанией Borland удобного и простого компилятора Turbo Pascal позволил ему занять лидирующие позиции и до сих пор изучаться в школах и институтах, хотя и как основы программирования, а не идеального языка для создания программ. Borland Pascal и используемый в Delphi язык Object Pascal основываются на Turbo Pascal и развивают его идеи. По сути, Delphi является компилятором языка Pascal. Самая первая версия Delphi объединила в себе надежный компилятор, визуальную среду для программиста и очень мощные возможности языка по работе с базами данных, и уже через год вышла Dephi 2 для 32-битной системы.
Из известных программ на Delphi написан “Total Commander” и “The Bat”
Рефал
«Зверский» язык, разработанный в 1966 году в ИМП АН СССР. Рефал широко применялся при разработке трансляторов с алгоритмических языков, в теоретической физике и прикладной математике, в проектировании информационных систем.
Программист на Рефале сам определяет структуру обрабатываемой информации, именно поэтому эффективность программы полностью зависит от него. На данный момент жив проект www.refal.net где язык пытается развиваться.
- языки программирования
- история
История языков программирования
Программирование — это сама основа цифровой эпохи, в которой мы живем сегодня. Каждый раз, когда вам нравится публикация в социальных сетях, вы отправляете электронное письмо или устанавливаете будильник на своем телефоне, язык программирования работает за кулисами, дергая за ниточки.
Но с чего все началось? И что стимулировало его рост в ведущую отрасль, существующую сегодня? Прежде всего, почему знание истории языков программирования важно для подбора ит специалистов и разработчиков ?
Эта ретроспектива продемонстрирует, насколько компьютерное программирование развилось за эти годы. Он вернет вас от ранних языков и сложного машинного кода к сложному, удобочитаемому языку, на котором сегодня работают наши любимые технологии.
Первый язык программирования
Знаете ли вы, что первый в мире язык компьютерного программирования был изобретен еще в 1843 году? Ада Лавлейс изобрела первый в истории машинный алгоритм для одной из первых вычислительных машин, который она записала на листе бумаги, потому что в то время компьютеров не существовало! С тех пор языки программирования, очевидно, прошли долгий путь, но для того, чтобы понять историю языков, нужно сначала понять их происхождение.
История языков программирования: хронология
Ниже приведен график истории языков программирования. Первые известные языки были сложными машинными кодами, которые вручную вводились в первые вычислительные машины. Как вы понимаете, компьютерное программирование быстро превратилось из машинных кодов в полностью автоматизированный, читаемый человеком код.
1843: Машинный алгоритм Ады Лавлейс
Ада Лавлейс изобретает первый в истории машинный алгоритм для разностной машины Чарльза Бэббиджа, который закладывает основу для всех языков программирования.
1944-45: Планкалкюль
Где-то между 1944-45 годами Конрад Цузе разработал первый «настоящий» язык программирования под названием Plankalkül (Расчет плана). Язык Zeus (помимо прочего) позволял создавать процедуры, в которых хранятся фрагменты кода, которые можно было вызывать снова и снова для выполнения рутинных операций.
1949: Язык Ассемблера
Ассемблер использовался в автоматическом калькуляторе с электронным запоминанием задержки (EDSAC). Ассемблер был разновидностью низкоуровневого языка программирования, который упростил язык машинного кода. Другими словами, конкретные инструкции, необходимые для работы с компьютером.
1949: Shortcode
Шорткод (или сокращенный код) был первым языком высокого уровня (HLL), предложенным Джоном Макколи в 1949 году. Однако именно Уильям Шмитт реализовал его для компьютера BINAC в том же году и для UNIVAC в 1950 году.
1952: Автокодирование
Автокод был общим термином, используемым для семейства языков программирования. Autocode, впервые разработанный Аликом Гленни для компьютера Mark 1 в Университете Манчестера, был первым в истории скомпилированным языком, который был реализован, что означает, что он может быть переведен непосредственно в машинный код с помощью программы, называемой компилятором. Автокод использовался на первых вычислительных машинах Ferranti Pegasus и Sirius в дополнение к Mark 1.
1957: Fortran
FORmula TRANslation или FORTRAN был создан Джоном Бэкусом и считается старейшим языком программирования, используемым сегодня. Язык программирования был создан для научных, математических и статистических вычислений высокого уровня. FORTRAN до сих пор используется в некоторых из самых передовых суперкомпьютеров в мире.
1958: ALGOL (Алгоритмический язык)
Алгоритмический язык или АЛГОЛ был создан совместным комитетом американских и европейских компьютерных ученых. Алгол послужил отправной точкой для разработки некоторых из наиболее важных языков программирования, включая Pascal, C, C ++ и Java.
1958: LISP (обработчик списков)
Процессор списков или LISP был изобретен Джоном Маккарти в Массачусетском технологическом институте (MIT). Первоначально предназначенный для искусственного интеллекта, LISP является одним из старейших языков программирования, которые все еще используются сегодня, и его можно использовать вместо Ruby или Python. Такие компании, как Acceleration, Boeing и Genworks, по-прежнему используют LISP в своих технических стеках.
1959: КОБОЛ (Общий бизнес-ориентированный язык)
Общий бизнес-ориентированный язык (COBOL) — это язык программирования, лежащий в основе многих процессоров кредитных карт, банкоматов, телефонных и сотовых вызовов, сигналов больниц и систем сигналов светофора (и это лишь некоторые из них). Разработкой языка руководила доктор Грейс Мюррей Хоппер, и он был разработан таким образом, чтобы его можно было использовать на компьютерах всех марок и типов. COBOL до сих пор используется в первую очередь для банковских систем.
1964: BASIC (универсальный символьный код инструкций для начинающих)
Универсальный код символических инструкций для начинающих или BASIC был разработан группой студентов Дартмутского колледжа. Этот язык был написан для студентов, которые плохо разбирались в математике или компьютерах. Этот язык был разработан основателями Microsoft Биллом Гейтсом и Полом Алленом и стал первым товарным продуктом компании.
1970: ПАСКАЛЬ
Названный в честь французского математика Блеза Паскаля, Никлаус Вирт разработал язык программирования в его честь. Он был разработан как средство обучения компьютерному программированию, что означало, что его легко освоить. Apple предпочитала его на заре своей деятельности из-за простоты использования и мощности.
Закрываем IT вакансии под ключ за 2 недели!
Помогаем новому сотруднику с адаптацией после выхода в компанию
1972: Smalltalk
Smalltalk, разработанный в исследовательском центре Xerox в Пало-Альто Аланом Кей, Адель Голдберг и Дэном Ингаллсом, позволял программистам изменять код на лету. Он представил множество аспектов языка программирования, которые сегодня являются видимыми языками, такими как Python, Java и Ruby. Такие компании, как Leafly, Logitech и CrowdStrike, заявляют, что используют Smalltalk в своих технических стеках.
1972: C (Си)
Разработан Деннисом Ричи из Bell Telephone Laboratories для использования с операционной системой Unix. Он был назван C, потому что был основан на более раннем языке под названием «B». Многие из ведущих в настоящее время языков являются производными от C, включая; C #, Java, JavaScript, Perl, PHP и Python. Он также использовался / до сих пор используется такими крупными компаниями, как Google, Facebook и Apple.
1972: SQL (в то время SEQUEL)
SQL был впервые разработан исследователями IBM Рэймондом Бойсом и Дональдом Чемберленом. SEQUEL (как его тогда называли) используется для просмотра и изменения информации, хранящейся в базах данных. В настоящее время язык является аббревиатурой — SQL, что означает язык структурированных запросов. Существует множество компаний, использующих SQL, и некоторые из них включают Microsoft и Accenture.
1980/81: Ада
Изначально Ada была разработана командой во главе с Джин Ичбиа из CUU Honeywell Bull по контракту с Министерством обороны США. Названный в честь математика середины 19-го века Ады Лавлейс, Ada представляет собой структурированный, статически типизированный, императивный, объектно-ориентированный язык программирования высокого уровня с широким спектром возможностей. Ада была расширена из других популярных в то время языков программирования, таких как Паскаль. Ada используется в системах управления воздушным движением в таких странах, как Австралия, Бельгия и Германия, а также во многих других транспортных и космических проектах.
1983: C ++
Бьярн Страуструп модифицировал язык C в Bell Labs, C ++ — это расширение C с такими улучшениями, как классы, виртуальные функции и шаблоны. Он был включен в 10 лучших языков программирования с 1986 года и получил статус Зала славы в 2003 году. C ++ используется в MS Office, Adobe Photoshop, игровых движках и другом высокопроизводительном программном обеспечении.
1983: Objective-C
Objective-C, разработанный Брэдом Коксом и Томом Лавом, является основным языком программирования, используемым для написания программного обеспечения для операционных систем Apple macOS и iOS.
1987: Perl
Perl был создан Ларри Уоллом и представляет собой универсальный язык программирования высокого уровня. Первоначально он был разработан как язык сценариев, предназначенный для редактирования текста, но в настоящее время он широко используется для многих целей, таких как CGI, приложения баз данных , системное администрирование, сетевое программирование и графическое программирование.
1990: Haskell
Haskell — это язык программирования общего назначения, названный в честь американского логика и математика Хаскелла Брукса Карри. Это чисто функциональный язык программирования, то есть в первую очередь математический. Он используется во многих отраслях, особенно в тех, которые имеют дело со сложными вычислениями, записями и обработкой чисел. Как и многие другие языки программирования той эпохи, не так уж часто можно увидеть, что Haskell используется для хорошо известных приложений. С учетом сказанного, язык программирования был использован для написания ряда игр, одна из которых — Nikki and the Robots.
1991: Python
Названный в честь британской комедийной труппы «Монти Пайтон», Python был разработан Гвидо Ван Россумом. Это универсальный язык программирования высокого уровня, созданный для поддержки различных стилей программирования и приятный в использовании (ряд руководств, примеров и инструкций часто содержат ссылки на Monty Python). Python по сей день является одним из самых популярных языков программирования в мире, который используют такие компании, как Google, Yahoo и Spotify.
1991: Visual Basic
Visual Basic, разработанный Microsoft, позволяет программистам использовать стиль перетаскивания для выбора и изменения предварительно выбранных фрагментов кода через графический интерфейс пользователя (GUI). В наши дни этот язык не используется слишком часто, однако Microsoft частично использовала Visual Basic для ряда своих приложений, таких как Word, Excel и Access.
1993: Ruby
Ruby, созданный Юкихиро Мацумото, представляет собой интерпретируемый язык программирования высокого уровня. Язык обучения, на который повлияли Perl, Ada, Lisp и Smalltalk — среди прочих. В основном Ruby используется для разработки веб-приложений и Ruby on Rails. Twitter, Hulu и Groupon — известные примеры компаний, использующих Ruby.
1995: Java
Java — это универсальный язык высокого уровня, созданный Джеймсом Гослингом для проекта интерактивного телевидения. Он обладает кросс-платформенной функциональностью и неизменно входит в число самых популярных языков программирования в мире. Java можно найти везде, от компьютеров до смартфонов и парковочных счетчиков.
1995: PHP
Ранее известный как «Персональная домашняя страница», что теперь означает «Препроцессор гипертекста», PHP был разработан Расмусом Лердорфом. Его основное применение включает создание и поддержку динамических веб-страниц, а также разработку на стороне сервера . Некоторые из крупнейших компаний по всему миру используют PHP, включая Facebook, Wikipedia, Digg, WordPress и Joomla.
1995: JavaScript
JavaScript был создан Бренданом Эйхом, этот язык в основном используется для динамической веб-разработки, документов PDF, веб-браузеров и виджетов рабочего стола. Почти каждый крупный веб-сайт использует JavaScript. Gmail, Adobe Photoshop и Mozilla Firefox включают несколько хорошо известных примеров.
2000: C #
Разработанный в Microsoft с надеждой на объединение вычислительных возможностей C ++ с простотой Visual Basic, C # основан на C ++ и имеет много общего с Java. Этот язык используется почти во всех продуктах Microsoft и используется в основном при разработке настольных приложений.
2003: Scala
Scala, разработанная Мартином Одерски, объединяет математическое функциональное программирование и организованное объектно-ориентированное программирование. Совместимость Scala с Java делает его полезным при разработке под Android. Linkedin, Twitter, Foursquare и Netflix — это всего лишь несколько примеров многих компаний, которые используют Scala в своих технических стеках.
2003: Groovy
Унаследованный от Java, Groovy был разработан Джеймсом Страчаном и Бобом МакВиртером. Язык повышает продуктивность, поскольку он лаконичен и прост в изучении. Некоторые известные компании, которые используют Groovy в своих технических стеках, — это Starbucks, Transferwise и Craftbase.
2009: Golang (Go)
Go был разработан Google для решения проблем, возникающих из-за больших программных систем. Благодаря своей простой и современной структуре Go завоевал популярность среди некоторых крупнейших технологических компаний по всему миру, таких как Google, Uber, Twitch и Dropbox.
2014: Swift
Разработанный Apple в качестве замены C, C ++ и Objective-C, Swift был разработан с целью быть проще, чем вышеупомянутые языки, и оставлять меньше места для ошибок. Универсальность Swift означает, что его можно использовать для настольных, мобильных и облачных приложений. Ведущее языковое приложение Duolingo запустило новое приложение, написанное на Swift.
Какие старые языки программирования все еще используются?
Не все языки программирования существуют вечно. Будь то результат развития технологий или просто замена более сложным языком. С учетом сказанного, ИТ специалисты по-прежнему используют некоторые старые языки программирования:
FORTRAN
Первоначальная версия FORTRAN была предложена в IBM Джоном Бэкусом еще в 1953 году. Это был первый компилятор-оптимизатор, который широко использовался в научной работе, поскольку его оптимизированный код выгодно конкурировал с написанным вручную кодом ассемблера. Этот язык до сих пор используется на некоторых из самых быстрых суперкомпьютеров в мире. С 1953 года была выпущена серия обновлений, последняя версия которых была выпущена в 2018 году.
COBOL
COBOL был разработан еще в 1959 году и был одним из первых языков программирования высокого уровня. Несмотря на то, что COBOL был изобретен так давно, он по-прежнему широко распространен. В одних только США 43% банковских систем построены на COBOL, что составляет 95% операций с банкоматами и 80% транзакций, совершаемых лично.
Ранние языки программирования Microsoft и Apple
Microsoft и Apple — две из самых фундаментальных компаний в истории языков программирования. BASIC (впервые выпущенный в 1964 году) был модифицирован основателями Microsoft Биллом Гейтсом и Полом Алленом в 1975 году. Их модифицированная версия стала Altair BASIC , который был первым продаваемым и распространяемым продуктом Microsoft, который привел к созданию компании.
Паскаль был предпочтительным языком программирования в первые дни Apple. Паскаль, изобретенный в начале 1970-х годов, понравился разработчикам Apple из-за его мощности и простоты использования. Однако, когда Apple приобрела библиотеку кода NeXTSTEP в 1996 году, Objective-C (который был лицензирован под NeXTSTEP) стал популярным языком, выбранным техническим гигантом.
Вывод
История языков программирования увлекательна. Кто бы мог подумать, что алгоритм середины 19 века проложит путь для технологического общества, в котором мы живем сегодня. От ранних машинных кодов до сложного, удобночитаемого кода, на котором сегодня работают наши любимые технологии, языки программирования прошли долгий путь. Несомненно, компьютерное программирование продолжит развиваться, как это происходило в течение последних 150 лет, и интересно смотреть, что принесет будущее.
За что я люблю ассемблер?
Этой статье уже почти 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 будут генерировать разный код; и даже один и тот же компилятор с разными настройками выдаст различный результат).
- Получаемый код даже самого умного и навороченного компилятора, как правило, можно оптимизировать (как по скорости, так и по размеру). К примеру, автоматическую векторизацию кода (приведение обычных скалярных вычислений к параллельным вычислениям с использованием SIMD: SSE, AVX и т.п.), компиляторы C/C++ делают весьма посредственно. А ещё можно изощриться и использовать неочевидные комбинации, сделав код короче и быстрее. Этим можно, конечно, заняться и на других языках, но на ассемблере больше простора для творчества. К тому же, это особый кайф, азарт, челлендж в некотором роде! Разве не прикольно написать программу, выполняющую полезные функции, весом менее 10 Кб? 🙂 Для сравнения: VCL-программа на Delphi 10.2 Tokyo, создающая пустое окно без какого-либо полезного функционала, весит в release-версии целых 2 Мб (а в debug-версии… кхм, 11 Мб). На C++Builder 10.2 Tokyo release-версия такой же программы, не требующая внешних библиотек, получится размером ≈ 2.7 Мб. Аналогичная программа на fasm будет занимать всего пару килобайт.
- Обычно одна строка кода на ЯВУ разворачивается в несколько (или даже десяток) инструкций процессора. А знаете ли вы о том, что некоторые инструкции процессора 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 (форум по низкоуровневому программированию и сборник статей). - Книги и статьи Криса Касперски (много).
- Официальная документация Intel (4 тома) [всё на английском, PDF].
- Официальная документация 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 [англ].
- Документация по оптимизации от Agner’а Fog’а (5 томов в одном архиве) [всё на английском].
- Михаил Гук. Аппаратные средства 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.
- Windows Driver Kit (WDK) – инструменты для разработчика драйверов (документация).
- 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.
Успехов вам!