stringtranslate.com

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

В компьютерном программировании язык ассемблера (альтернативно язык ассемблера [1] или символический машинный код ), [2] [3] [4], часто называемый просто ассемблером и обычно сокращаемый как ASM или asm , представляет собой любой язык программирования низкого уровня с очень сильное соответствие между инструкциями языка и инструкциями машинного кода архитектуры . [5] Язык ассемблера обычно имеет один оператор на машинную инструкцию (1:1), но константы, комментарии , директивы ассемблера , [6] символические метки , например, ячеек памяти , регистров и макросов [7] [1] обычно также поддерживается.

Первый ассемблерный код, в котором язык используется для представления инструкций машинного кода, можно найти в работе Кэтлин и Эндрю Дональда Бутов 1947 года «Кодирование для ARC» . [8] Ассемблерный код преобразуется в исполняемый машинный код с помощью служебной программы , называемой ассемблером . Термин «ассемблер» обычно приписывают Уилксу , Уилеру и Гиллу в их книге 1951 года « Подготовка программ для электронного цифрового компьютера » [9] , которые, однако, использовали этот термин для обозначения «программы, которая собирает другую программу, состоящую из нескольких разделы в единую программу». [10] Процесс преобразования называется сборкой , как и сборка исходного кода . Вычислительный этап, когда ассемблер обрабатывает программу, называется временем сборки .

Поскольку сборка зависит от инструкций машинного кода, каждый язык ассемблера [nb 1] специфичен для конкретной компьютерной архитектуры . [11] [12] [13]

Иногда для одной и той же архитектуры существует более одного ассемблера, а иногда ассемблер специфичен для операционной системы или конкретных операционных систем. Большинство языков ассемблера не предоставляют специального синтаксиса для вызовов операционной системы, и большинство языков ассемблера могут использоваться универсально с любой операционной системой, [nb 2] , поскольку язык обеспечивает доступ ко всем реальным возможностям процессора , на которых основаны все механизмы системных вызовов . в конце концов отдых. В отличие от языков ассемблера, большинство языков программирования высокого уровня, как правило, переносимы на несколько архитектур, но требуют интерпретации или компиляции , а это гораздо более сложные задачи, чем ассемблирование.

В первые десятилетия развития вычислительной техники и системное , и прикладное программирование было обычным явлением полностью на языке ассемблера. Несмотря на то, что они по-прежнему незаменимы для некоторых целей, большая часть программирования теперь выполняется на интерпретируемых и компилируемых языках более высокого уровня. В книге « Нет серебряной пули » Фред Брукс резюмировал последствия отказа от программирования на языке ассемблера: «Несомненно, самым мощным стимулом для повышения производительности, надежности и простоты программного обеспечения стало постепенное использование языков высокого уровня для программирования. Большинство наблюдателей следует отдать должное этому развитию, по крайней мере, в пятикратном повышении производительности и сопутствующем повышении надежности, простоты и понятности». [14]

Сегодня типично использовать небольшие объемы кода на языке ассемблера в более крупных системах, реализованных на языке более высокого уровня, из соображений производительности или для прямого взаимодействия с оборудованием способами, не поддерживаемыми языком более высокого уровня. Например, чуть менее 2% исходного кода ядра Linux версии 4.9 написано на ассемблере; более 97% написано на C. [15]

Синтаксис языка ассемблера

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

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

Терминология

Ключевые идеи

Ассемблер

Программа на ассемблере создает объектный код путем перевода комбинаций мнемоники и синтаксиса операций и режимов адресации в их числовые эквиваленты. Это представление обычно включает в себя код операциикод операции »), а также другие биты управления и данные. Ассемблер также вычисляет константные выражения и разрешает символические имена для ячеек памяти и других объектов. [20] Использование символических ссылок является ключевой особенностью ассемблеров, позволяющей избежать утомительных вычислений и ручного обновления адресов после модификаций программы. Большинство ассемблеров также включают в себя макросы для выполнения текстовых подстановок – например, для генерации общих коротких последовательностей инструкций как встроенных , а не вызываемых подпрограмм .

Некоторые ассемблеры также могут выполнять некоторые простые типы оптимизации , специфичные для набора команд . Конкретным примером этого могут быть вездесущие ассемблеры x86 от различных производителей. Называемые jump-sizing , [20] большинство из них способны выполнять замену инструкций перехода (длинные прыжки заменяются короткими или относительными прыжками) за любое количество проходов по запросу. Другие могут даже выполнять простую перестановку или вставку инструкций, например некоторые ассемблеры для RISC-архитектур , которые могут помочь оптимизировать разумное планирование инструкций для максимально эффективного использования конвейера ЦП . [21]

Ассемблер был доступен с 1950-х годов как первый шаг по сравнению с машинным языком и перед языками программирования высокого уровня, такими как Fortran , Algol , COBOL и Lisp . Также существовало несколько классов трансляторов и полуавтоматических генераторов кода со свойствами, схожими как с ассемблером, так и с языками высокого уровня, причем Speedcode , возможно, является одним из наиболее известных примеров.

Может существовать несколько ассемблеров с разным синтаксисом для конкретного процессора или архитектуры набора команд . Например, инструкция по добавлению данных памяти в регистр процессора семейства x86 может быть написана add eax,[ebx]в исходном синтаксисе Intel , тогда как она будет записана addl (%ebx),%eaxв синтаксисе AT&T, используемом ассемблером GNU . Несмотря на разный внешний вид, разные синтаксические формы обычно генерируют один и тот же числовой машинный код . Один ассемблер также может иметь разные режимы для поддержки вариаций синтаксических форм, а также их точных семантических интерпретаций (например, синтаксис FASM , синтаксис TASM , идеальный режим и т. д., в частном случае программирования на ассемблере x86 ).

Количество проходов

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

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

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

Пример: в следующем фрагменте кода однопроходный ассемблер сможет определить адрес обратной ссылки BKWD при сборке оператора S2 , но не сможет определить адрес прямой ссылки FWD при сборке оператора ветвления S1 . ; действительно, FWD может быть неопределенным. Двухпроходный ассемблер определит оба адреса на первом этапе, поэтому они будут известны при генерации кода на втором этапе.

S1 Б ВПЕРЕД ...ПЕРЕДНЕЕ ЭКВЮ * ...БКВД ЭКВ* ...S2 Б БКВД

Сборщики высокого уровня

Более сложные ассемблеры высокого уровня предоставляют такие языковые абстракции, как:

Более подробную информацию см. в разделе Языковой дизайн ниже.

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

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

Например, инструкция ниже сообщает процессору x86 / IA-32 о необходимости немедленного перемещения 8-битного значения в регистр . Двоичный код этой инструкции — 10110, за которым следует 3-битный идентификатор используемого регистра. Идентификатор регистра AL — 000, поэтому следующий машинный код загружает в регистр AL данные 01100001. [24]

10110000 01100001

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

Б0 61

Здесь B0означает «Переместить копию следующего значения в AL » и 61является шестнадцатеричным представлением значения 01100001, которое равно 97 в десятичном формате . Язык ассемблера семейства 8086 предоставляет мнемоническое обозначение MOV (сокращение от move ) для таких инструкций, поэтому приведенный выше машинный код можно записать на языке ассемблера следующим образом, дополнив его, если необходимо, пояснительным комментарием после точки с запятой. Это гораздо легче читать и запоминать.

МОВ АЛ , 61ч ; Загрузите AL с 97 десятичным числом (61 шестнадцатеричным).   

В некоторых языках ассемблера (включая этот) одна и та же мнемоника, такая как MOV, может использоваться для семейства связанных инструкций по загрузке, копированию и перемещению данных, будь то непосредственные значения, значения в регистрах или ячейки памяти, на которые указывает значения в регистрах или по непосредственным (то есть прямым) адресам. Другие ассемблеры могут использовать отдельные мнемоники кода операции, такие как L для «перемещения памяти в регистр», ST для «перемещения регистра в память», LR для «перемещения регистра в регистр», MVI для «перемещения непосредственного операнда в память» и т. д.

Если одна и та же мнемоника используется для разных инструкций, это означает, что мнемоника соответствует нескольким различным двоичным кодам инструкций, за исключением данных (например, 61hв этом примере), в зависимости от операндов, следующих за мнемоникой. Например, для процессоров x86/IA-32 синтаксис языка ассемблера Intel MOV AL, AHпредставляет собой инструкцию, которая перемещает содержимое регистра AH в регистр AL . Шестнадцатеричная форма этой инструкции [nb 3] :

88 Е0

Первый байт, 88h, идентифицирует перемещение между регистром размером в байт и другим регистром или памятью, а второй байт, E0h, кодируется (с тремя битовыми полями), чтобы указать, что оба операнда являются регистрами, источником является AH. , а пункт назначения — AL .

В таком случае, когда одна и та же мнемоника может представлять более одной двоичной инструкции, ассемблер определяет, какую инструкцию сгенерировать, проверяя операнды. В первом примере операнд 61hявляется допустимой шестнадцатеричной числовой константой и не является допустимым именем регистра, поэтому B0применима только инструкция. Во втором примере операндом AHявляется допустимое имя регистра, а не допустимая числовая константа (шестнадцатеричная, десятичная, восьмеричная или двоичная), поэтому 88применима только инструкция.

Языки ассемблера всегда проектируются таким образом, чтобы такое отсутствие двусмысленности повсеместно обеспечивалось их синтаксисом. Например, в языке ассемблера Intel x86 шестнадцатеричная константа должна начинаться с цифровой цифры, чтобы шестнадцатеричное число «A» (равное десятичному десяти) было записано как 0Ahили 0AH, а не AH, в частности, чтобы оно не могло выглядеть как имя регистра AH . (То же самое правило также предотвращает двусмысленность имен регистров BH , CH и DH , а также любого определяемого пользователем символа, который заканчивается на букву H и в противном случае содержит только символы, являющиеся шестнадцатеричными цифрами, например слово «BEACH». ".)

Возвращаясь к исходному примеру, в то время как код операции x86 10110000 ( B0) копирует 8-битное значение в регистр AL , 10110001 ( B1) перемещает его в CL , а 10110010 ( B2) делает это в DL . Примеры языка ассемблера для них приведены ниже. [24]

МОВ АЛ , 1 час ; Загрузить AL с немедленным значением 1 MOV CL , 2h ; Загрузить CL с непосредственным значением 2 MOV DL , 3h ; Загрузить DL с непосредственным значением 3         

Синтаксис MOV также может быть более сложным, как показывают следующие примеры. [25]

MOV EAX , [ EBX ] ; Переместить 4 байта памяти по адресу, содержащемуся в EBX, в EAX MOV [ ESI + EAX ], CL ; Переместить содержимое CL в байт по адресу ESI+EAX MOV DS , DX ; Переместите содержимое DX в сегментный регистр DS.         

В каждом случае мнемоника MOV транслируется ассемблером непосредственно в один из кодов операций 88-8C, 8E, A0-A3, B0-BF, C6 или C7, и программисту обычно не нужно знать или запоминать какой именно. [24]

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

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

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

Двумя примерами процессоров, которые имеют два разных набора мнемоник, являются семейство Intel 8080 и Intel 8086/8088. Поскольку Intel заявила об авторских правах на свою мнемонику языка ассемблера (по крайней мере, на каждой странице своей документации, опубликованной в 1970-х и начале 1980-х годов), некоторые компании, которые самостоятельно производили процессоры, совместимые с наборами инструкций Intel, изобрели свои собственные мнемоники. ЦП Zilog Z80 , усовершенствованный процессор Intel 8080A , поддерживает все инструкции 8080A, а также многие другие; Zilog изобрел совершенно новый язык ассемблера не только для новых инструкций, но и для всех инструкций 8080A. Например, там, где Intel использует мнемоники MOV , MVI , LDA , STA , LXI , LDAX , STAX , LHLD и SHLD для различных инструкций передачи данных, язык ассемблера Z80 использует мнемонику LD для всех из них. Похожий случай – процессоры NEC V20 и V30 , усовершенствованные копии Intel 8086 и 8088 соответственно. Как и Zilog с Z80, NEC изобрела новую мнемонику для всех инструкций 8086 и 8088, чтобы избежать обвинений в нарушении авторских прав Intel. (Сомнительно, что такие авторские права могут быть действительными, и более поздние компании-производители процессоров, такие как AMD [nb 4] и Cyrix , переиздали мнемонику инструкций Intel x86/IA-32 именно без разрешения и юридического наказания.) Сомнительно, что на практике многие люди тот, кто программировал V20 и V30, на самом деле писал на ассемблере NEC, а не на языке Intel; поскольку любые два языка ассемблера для одной и той же архитектуры набора команд изоморфны (что-то вроде английского и Pig Latin ), нет необходимости использовать собственный опубликованный язык ассемблера производителя с продуктами этого производителя.

Языковой дизайн

Основные элементы

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

Мнемоника опкода и расширенная мнемоника

Инструкции (операторы) на языке ассемблера, как правило, очень просты, в отличие от инструкций в языках высокого уровня . Как правило, мнемоника — это символическое имя для одной исполняемой инструкции машинного языка (код операции ), и для каждой инструкции машинного языка определена по крайней мере одна мнемоника кода операции. Каждая инструкция обычно состоит из операции или кода операции плюс ноль или более операндов . Большинство инструкций относятся к одному значению или паре значений. Операнды могут быть непосредственными (значения, закодированные в самой инструкции), регистрами, указанными в инструкции или подразумеваемыми, или адресами данных, расположенными в другом месте в памяти. Это определяется базовой архитектурой процессора: ассемблер просто отражает, как работает эта архитектура. Расширенная мнемоника часто используется для указания комбинации кода операции с определенным операндом, например, ассемблеры System/360 используют Bв качестве расширенной мнемоники for BCс маской 15 и NOP(«НЕТ ОПЕРАЦИИ» – ничего не делать в течение одного шага) для BCwith маска 0.

Расширенная мнемоника часто используется для поддержки специализированного использования инструкций, часто для целей, не очевидных из названия инструкции. Например, многие процессоры не имеют явной инструкции NOP, но имеют инструкции, которые можно использовать для этой цели. В процессорах 8086 инструкция используется для псевдооперационного кода для кодирования инструкции . Некоторые дизассемблеры распознают это и декодируют инструкцию как . Точно так же ассемблеры IBM для System/360 и System/370 используют расширенную мнемонику и для и с нулевыми масками. В архитектуре SPARC они известны как синтетические инструкции . [26]xchg ax,axnopnopxchg ax,axxchg ax,axnopNOPNOPRBCBCR

Некоторые ассемблеры также поддерживают простые встроенные макрокоманды, которые генерируют две или более машинные инструкции. Например, в некоторых ассемблерах Z80 команда ld hl,bcраспознается как генерируемая, ld l,cза которой следует ld h,b. [27] Их иногда называют псевдокодами операций .

Мнемоника — это произвольные символы; В 1985 году IEEE опубликовал Стандарт 694 для единого набора мнемоник, который должен использоваться всеми ассемблерами. С тех пор стандарт был отменен.

Директивы данных

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

Директивы сборки

Директивы ассемблера, также называемые псевдокодами операций, псевдооперациями или псевдооперациями, представляют собой команды, данные ассемблеру, «предписывающие ему выполнять операции, отличные от инструкций ассемблирования». [20] Директивы влияют на работу ассемблера и «могут повлиять на объектный код, таблицу символов, файл листинга и значения внутренних параметров ассемблера». Иногда термин «псевдооперационный код» зарезервирован для директив, генерирующих объектный код, например тех, которые генерируют данные. [28]

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

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

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

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

Макросы

Многие ассемблеры поддерживают предопределенные макросы , а другие поддерживают определяемые программистом (и многократно переопределяемые) макросы, включающие последовательности текстовых строк, в которые встроены переменные и константы. Макроопределение чаще всего [nb 5] представляет собой смесь операторов ассемблера, например, директив, символических машинных инструкций и шаблонов для операторов ассемблера. Эта последовательность текстовых строк может включать коды операций или директивы. После определения макроса его имя можно использовать вместо мнемоники. Когда ассемблер обрабатывает такой оператор, он заменяет этот оператор текстовыми строками, связанными с этим макросом, а затем обрабатывает их так, как если бы они существовали в файле исходного кода (включая, в некоторых ассемблерах, расширение любых макросов, существующих в заменяющем тексте). . Макросы в этом смысле восходят к автокодерам IBM 1950-х годов. [29]

У ассемблеров макросов обычно есть директивы, например, для определения макросов, определения переменных, установки переменных в результат арифметического, логического или строкового выражения, итерации, условной генерации кода. Некоторые из этих директив могут быть ограничены для использования в определении макроса, например, MEXIT в HLASM , в то время как другие могут быть разрешены в открытом коде (вне определений макросов), например, AIF и COPY в HLASM.

На языке ассемблера термин «макрос» представляет собой более обширное понятие, чем в некоторых других контекстах, например, препроцессор в языке программирования C , где его директива #define обычно используется для создания коротких однострочных макросов. Макросинструкции ассемблера, как и макросы в PL/I и некоторых других языках, сами по себе могут быть длинными «программами», выполняемыми путем интерпретации ассемблером во время ассемблера.

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

Сборщики макросов часто позволяют макросам принимать параметры . Некоторые ассемблеры включают в себя довольно сложные макроязыки, включающие такие элементы языка высокого уровня, как необязательные параметры, символические переменные, условные выражения, манипуляции со строками и арифметические операции, которые можно использовать во время выполнения данного макроса и позволяют макросам сохранять контекст или обмениваться информацией. . Таким образом, макрос может генерировать многочисленные инструкции языка ассемблера или определения данных на основе аргументов макроса. Это можно использовать, например, для создания структур данных в стиле записи или « развернутых » циклов, или для создания целых алгоритмов на основе сложных параметров. Например, макрос «сортировки» может принять спецификацию сложного ключа сортировки и сгенерировать код, созданный для этого конкретного ключа, не нуждаясь в тестах во время выполнения, которые потребуются для общей процедуры интерпретации спецификации. Можно считать, что организация, использующая язык ассемблера, который был значительно расширен с помощью такого набора макросов, работает на языке более высокого уровня, поскольку такие программисты не работают с концептуальными элементами компьютера самого низкого уровня. Подчеркивая этот момент, макросы использовались для реализации ранней виртуальной машины в SNOBOL4 (1967), которая была написана на языке реализации SNOBOL (SIL), языке ассемблера для виртуальной машины. Целевая машина переведет это в свой собственный код с помощью ассемблера макросов . [30] Это обеспечило высокую степень мобильности для того времени.

Макросы использовались для настройки крупномасштабных программных систем для конкретных клиентов в эпоху мэйнфреймов, а также использовались персоналом клиентов для удовлетворения потребностей своих работодателей путем создания конкретных версий операционных систем производителя. Это было сделано, например, системными программистами, работавшими с системой/виртуальной машиной IBM Conversational Monitor System/Virtual Machine ( VM/CMS ) и с надстройками IBM для «обработки транзакций в реальном времени», системой управления информацией о клиентах CICS и ACP / TPF . авиационная/финансовая система, которая возникла в 1970-х годах и до сих пор использует множество крупных компьютерных систем бронирования (CRS) и систем кредитных карт.

Также можно использовать исключительно возможности ассемблера по обработке макросов для генерации кода, написанного на совершенно разных языках, например, для создания версии программы на COBOL с использованием чистой программы макроса ассемблера, содержащей строки кода COBOL внутри операторов времени сборки. инструктируя ассемблер сгенерировать произвольный код. IBM OS/360 использует макросы для создания системы . Пользователь указывает параметры, кодируя серию ассемблерных макросов. Сборка этих макросов генерирует поток заданий для построения системы, включая язык управления заданиями и операторы управления утилитами .

Это связано с тем, что, как стало понятно в 1960-х годах, концепция «макрообработки» независима от концепции «сборки», причем первая, выражаясь современными терминами, представляет собой скорее обработку текста, обработку текста, чем генерацию объектного кода. Концепция обработки макросов появилась и появляется в языке программирования C, который поддерживает «инструкции препроцессора» для установки переменных и выполнения условных проверок их значений. В отличие от некоторых предыдущих макропроцессоров внутри ассемблеров, препроцессор C не является полным по Тьюрингу, поскольку в нем отсутствует возможность зацикливания или «перехода», что позволяет программам зацикливаться.

Несмотря на мощь обработки макросов, она вышла из употребления во многих языках высокого уровня (основными исключениями являются C , C++ и PL/I), оставаясь неизменным для ассемблеров.

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

фу: макрос азагрузить а*б

намерение состояло в том, чтобы вызывающая сторона предоставила имя переменной, а «глобальная» переменная или константа b использовалась для умножения «a». Если foo вызывается с параметром a-c, происходит раскрытие макроса load a-c*b. Чтобы избежать любой возможной двусмысленности, пользователи макропроцессоров могут заключать в круглые скобки формальные параметры внутри определений макросов, или вызывающие программы могут заключать в скобки входные параметры. [31]

Поддержка структурированного программирования

Были написаны пакеты макросов, предоставляющие элементы структурированного программирования для кодирования потока выполнения. Самый ранний пример этого подхода был в наборе макросов Concept-14 [32] , первоначально предложенном Харланом Миллсом (март 1970 г.) и реализованном Марвином Кесслером из подразделения Федеральных систем IBM, который предоставил IF/ELSE/ENDIF и аналогичный поток управления. блоки для программ на ассемблере OS/360. Это был способ уменьшить или исключить использование операций GOTO в ассемблерном коде, одного из основных факторов, вызывающих спагетти-код на языке ассемблера. Этот подход получил широкое распространение в начале 1980-х годов (последние дни широкомасштабного использования языка ассемблера). Набор инструментов High Level Assembler Toolkit от IBM [33] включает такой пакет макросов.

Любопытной разработкой был A-Natural, «поток-ориентированный» ассемблер для 8080/ Z80 , процессоров [34] от Whitesmiths Ltd. (разработчиков Unix -подобной операционной системы Idris и, как сообщалось, первого коммерческого компилятора C) . ). Язык был классифицирован как ассемблер, потому что он работал с необработанными машинными элементами, такими как коды операций , регистры и ссылки на память; но он включал синтаксис выражений, указывающий порядок выполнения. Круглые скобки и другие специальные символы, а также конструкции блочно-ориентированного структурированного программирования контролировали последовательность генерируемых инструкций. A-natural был создан как объектный язык компилятора C, а не для ручного кодирования, но его логический синтаксис завоевал некоторых поклонников.

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

Ассемблер с мощным механизмом макросов позволяет структурировать программирование с помощью макросов, таких как макрос переключения, поставляемый в пакете Masm32 (этот код представляет собой полную программу):

включить \ masm32 \ include \ masm32rt.inc ; используйте библиотеку Masm32 .code demomain: REPEAT 20 переключатель rv ( nrandom , 9 ) ; сгенерировать число от 0 до 8 mov ecx , 7 case 0 print «case 0» case ecx ; в отличие от большинства других языков программирования, выведите «case 7» ; переключатель Masm32 позволяет «вариативные случаи» case 1 .. 3 .if eax == 1 напечатать «случай 1» .elseif eax == 2 напечатать «случай 2» .else напечатать «случаи от 1 до 3: другое» .endif case 4 , 6 , 8 напечатать «случаи 4, 6 или 8» по умолчанию mov ebx , 19 ; напечатайте 20 звезд . Повторите печать «*» dec ebx . До подписания? ; цикл до тех пор, пока не будет установлен флаг знака endw print chr$ ( 13 , 10 ) ENDM выход end demomain                                  

Использование языка ассемблера

Историческая перспектива

Языки ассемблера не были доступны в то время, когда был представлен компьютер с хранимой программой . Кэтлин Бут «приписывается изобретение языка ассемблера» [37] [38] на основе теоретической работы, которую она начала в 1947 году, когда работала над ARC2 в Биркбеке, Лондонский университет, после консультации Эндрю Бута (впоследствии ее мужа) с математиком Джоном фон Нейман и физик Герман Голдстайн из Института перспективных исследований . [38] [39]

В конце 1948 года электронный автоматический калькулятор с задержкой хранения (EDSAC) имел ассемблер (называемый «начальными заказами»), интегрированный в его программу начальной загрузки . В нем использовалась однобуквенная мнемоника, разработанная Дэвидом Уилером , которого Компьютерное общество IEEE считает создателем первого «ассемблера». [20] [40] [41] В отчетах EDSAC был введен термин «сборка» для обозначения процесса объединения полей в командное слово. [42] SOAP ( символическая оптимальная программа сборки ) — язык ассемблера для компьютера IBM 650, написанный Стэном Поли в 1955 году. [43]

Языки ассемблера устраняют большую часть подверженного ошибкам, утомительного и трудоемкого программирования первого поколения , необходимого для самых ранних компьютеров, освобождая программистов от утомительной работы, такой как запоминание числовых кодов и вычисление адресов. Когда-то они широко использовались для всех видов программирования. Однако к концу 1950-х годов их использование было в значительной степени вытеснено языками более высокого уровня в поисках повышения производительности программирования . Сегодня язык ассемблера по-прежнему используется для прямого манипулирования оборудованием, доступа к специализированным инструкциям процессора или для решения критических проблем с производительностью. [44] Типичным применением являются драйверы устройств , низкоуровневые встроенные системы и системы реального времени (см. § Текущее использование).

Многие программы написаны полностью на языке ассемблера. Burroughs MCP (1961) был первым компьютером, операционная система которого не была полностью разработана на языке ассемблера; он был написан на проблемно-ориентированном языке исполнительных систем (ESPOL), диалекте Алгола. Многие коммерческие приложения также были написаны на языке ассемблера, включая большое количество программного обеспечения для мэйнфреймов IBM , написанного крупными корпорациями. COBOL , FORTRAN и некоторые PL/I в конечном итоге вытеснили большую часть этой работы, хотя ряд крупных организаций сохранили инфраструктуры приложений на языке ассемблера вплоть до 1990-х годов.

Язык ассемблера долгое время был основным языком разработки для 8-битных домашних компьютеров, таких как 8-битное семейство Atari , Apple II , MSX , ZX Spectrum и Commodore 64 . Интерпретируемые диалекты BASIC в этих системах предлагают недостаточную скорость выполнения и недостаточные возможности для полного использования преимуществ доступного оборудования. Эти системы имеют серьезные ограничения по ресурсам, своеобразную архитектуру памяти и дисплея и предоставляют ограниченные системные услуги. Существует также несколько компиляторов языков высокого уровня, подходящих для использования на микрокомпьютерах. Аналогичным образом, язык ассемблера является выбором по умолчанию для 8-битных консолей, таких как Atari 2600 и Nintendo Entertainment System .

Ключевое программное обеспечение для IBM PC-совместимых компьютеров было написано на языке ассемблера, например MS-DOS , Turbo Pascal и электронная таблица Lotus 1-2-3 . Поскольку скорость компьютеров росла в геометрической прогрессии, язык ассемблера стал инструментом для ускорения отдельных частей программ, таких как рендеринг Doom , а не доминирующим языком разработки. В 1990-х годах ассемблер использовался для повышения производительности таких систем, как Sega Saturn [45], а также в качестве основного языка для аркадного оборудования на базе интегрированного ЦП/ГП TMS34010 , такого как Mortal Kombat и NBA Jam .

Текущее использование

Были споры о полезности и производительности языка ассемблера по сравнению с языками высокого уровня. [46]

Хотя язык ассемблера имеет определенные ниши, где он важен (см. ниже), существуют и другие инструменты для оптимизации. [47]

По состоянию на июль 2017 года в индексе популярности языка программирования TIOBE язык ассемблера занимает 11 место, опережая, например, Visual Basic . [48] ​​Ассемблер можно использовать для оптимизации скорости или размера. Утверждается , что в случае оптимизации скорости современные оптимизирующие компиляторы [49] преобразуют языки высокого уровня в код, который может работать так же быстро, как рукописный ассемблер, несмотря на встречные примеры. [50] [51] [52] Сложность современных процессоров и подсистем памяти делает эффективную оптимизацию все более сложной для компиляторов, а также для программистов-ассемблеров. [53] [54] Более того, повышение производительности процессоров привело к тому, что большинство процессоров большую часть времени простаивают, [55] с задержками, вызванными предсказуемыми узкими местами, такими как промахи в кэше, операции ввода-вывода и подкачка . Благодаря этому скорость выполнения исходного кода не является проблемой для многих программистов.

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

Язык ассемблера по-прежнему преподается в большинстве программ по информатике и электронной инженерии . Хотя сегодня немногие программисты регулярно работают с языком ассемблера как с инструментом, лежащие в его основе концепции остаются важными. Такие фундаментальные темы, как двоичная арифметика , распределение памяти , обработка стека , кодирование набора символов , обработка прерываний и проектирование компилятора , было бы трудно изучить подробно, не имея представления о том, как компьютер работает на аппаратном уровне. Поскольку поведение компьютера в основном определяется его набором команд, логичным способом изучения таких концепций является изучение языка ассемблера. Большинство современных компьютеров имеют схожие наборы команд. Поэтому изучения одного языка ассемблера достаточно, чтобы усвоить: I) основные понятия; II) распознавать ситуации, в которых использование языка ассемблера может быть уместным; и III), чтобы увидеть, насколько эффективный исполняемый код может быть создан на языках высокого уровня. [23]

Типичные области применения

Смотрите также

Примечания

  1. ^ Кроме метаассемблеров
  2. ^ Однако это не означает, что программы на ассемблере, реализующие эти языки, универсальны.
  3. ^ Это одна из двух дублирующих форм этой инструкции, которые работают одинаково. 8086 и некоторые другие ЦП конца 1970-х – начала 1980-х годов имеют избыточность в наборах команд, поскольку инженерам было проще спроектировать эти ЦП (чтобы они помещались на кремниевые чипы ограниченных размеров) с избыточными кодами, чем устранять их (см. безразличные термины ). Каждый ассемблер обычно генерирует только одну из двух или более избыточных кодировок инструкций, но дизассемблер обычно распознает любую из них.
  4. ^ AMD производила процессоры Intel 8086, 8088 и 80286 второго источника и, возможно, процессоры 8080A и/или 8085A по лицензии Intel, но, начиная с 80386, Intel отказывалась делиться с кем-либо своими разработками процессоров x86 - AMD подала в суд по этому поводу. за нарушение контракта, а AMD разработала, произвела и продала 32-битные и 64-битные процессоры семейства x86 без помощи или одобрения Intel.
  5. ^ В 7070 Autocoder определение макроса представляет собой программу-генератор макросов 7070, которую вызывает ассемблер; Autocoder предоставляет специальные макросы для использования генераторами макросов.

Рекомендации

  1. ^ ab «Язык Ассемблер». Ассемблер высокого уровня для z/OS, z/VM и z/VSE, справочник по языку, версия 1, выпуск 6. IBM . 2014 [1990]. SC26-4940-06.
  2. ^ «Сборка: Обзор» (PDF) . Информатика и инженерия. Инженерный колледж Университета штата Огайо . 2016. Архивировано (PDF) из оригинала 24 марта 2020 г. Проверено 24 марта 2020 г.
  3. Арчер, Бенджамин (ноябрь 2016 г.). Язык ассемблера для студентов. Северный Чарльстон, Южная Каролина, США: Независимое издательство CreateSpace . ISBN 978-1-5403-7071-6. Язык ассемблера также можно назвать символическим машинным кодом.
  4. ^ Стрейб, Джеймс Т. (2020). «Руководство по языку ассемблера». Темы бакалавриата по информатике . Чам: Международное издательство Springer. дои : 10.1007/978-3-030-35639-2. ISBN 978-3-030-35638-5. ISSN  1863-7310. S2CID  195930813. Программирование на языке ассемблера имеет те же преимущества, что и программирование на машинном языке, за исключением того, что оно проще.
  5. ^ Саксон, Джеймс А.; Плетт, Уильям С. (1962). Программирование IBM 1401, самоучитель по программированию. Энглвуд Клиффс, Нью-Джерси, США: Прентис-Холл . LCCN  62-20615.(Примечание. Использование термина «программа сборки» .)
  6. ^ Корнелис, А.Ф. (2010) [2003]. «Ассемблер высокого уровня – обзор кодов операций, директивы ассемблера». Архивировано из оригинала 24 марта 2020 г. Проверено 24 марта 2020 г.
  7. ^ «Макроинструкции». Ассемблер высокого уровня для z/OS, z/VM и z/VSE, справочник по языку, версия 1, выпуск 6. IBM . 2014 [1990]. SC26-4940-06.
  8. ^ Бут, Эндрю Д; Бриттен, Кэтлин Х.В. (1947). Кодирование для ARC (PDF) . Институт перспективных исследований, Принстон . Проверено 4 ноября 2022 г.
  9. ^ Уилкс, Морис Винсент ; Уилер, Дэвид Джон ; Гилл, Стэнли Дж. (1951). Подготовка программ для электронной цифровой вычислительной машины (Переиздание 1982 г., изд.). Издательство Томаш . ISBN 978-0-93822803-5. ОСЛК  313593586.
  10. ^ Фэйрхед, Гарри (16 ноября 2017 г.). «История компьютерных языков - классическое десятилетие, 1950-е годы». Я Программист . Архивировано из оригинала 2 января 2020 г. Проверено 06 марта 2020 г.
  11. ^ «Как языки ассемблера зависят от операционных систем?». Обмен стеками . Stack Exchange Inc. 28 июля 2011 г. Архивировано из оригинала 24 марта 2020 г. Проверено 24 марта 2020 г.(Примечание. Системные вызовы часто различаются, например, для MVS , VSE и VM/CMS; форматы двоичных/исполняемых файлов для разных операционных систем также могут различаться.)
  12. ^ Аустерлиц, Ховард (2003). «Языки программирования». Методы сбора данных с использованием ПК . Эльзевир. стр. 326–360. дои : 10.1016/b978-012068377-2/50013-9. ISBN 9780120683772. Язык Ассемблера (или Ассемблер) — это компилируемый компьютерный язык низкого уровня. Он зависит от процессора, поскольку по сути преобразует мнемонику ассемблера непосредственно в команды, которые понимает конкретный процессор, на основе «один к одному». Эти мнемоники Ассемблера представляют собой набор команд для этого процессора.
  13. ^ Карнс, Бо (27 апреля 2022 г.). «Изучите программирование на языке ассемблера с помощью ARM». freeCodeCamp.org . Проверено 21 июня 2022 г. Язык ассемблера часто зависит от конкретной компьютерной архитектуры, поэтому существует несколько типов языков ассемблера. ARM становится все более популярным языком ассемблера.
  14. ^ Брукс, Фредерик П. (1986). «Нет серебряной пули — суть и случайность в разработке программного обеспечения». Материалы Десятой Всемирной компьютерной конференции ИФИП . стр. 1069–1076.
  15. ^ Ангиано, Рикардо. «Основная строка ядра Linux 4.9 sloccount.txt». Суть . Проверено 4 мая 2022 г.
  16. ^ Дэйнтит, Джон, изд. (2019). «метаассемблер». Словарь вычислительной техники . Архивировано из оригинала 24 марта 2020 г. Проверено 24 марта 2020 г.
  17. ^ Xerox Data Systems (октябрь 1975 г.). Xerox Meta-Symbol Sigma 5-9 Справочное руководство по компьютерному языку и операциям (PDF) . п. VI. Архивировано (PDF) из оригинала 9 октября 2022 г. Проверено 7 июня 2020 г. Используемый в качестве метаассемблера, он позволяет пользователю разрабатывать свои собственные языки программирования и генерировать процессоры для таких языков с минимальными усилиями.
  18. ^ Компьютерные системы Сперри Univac (1977). Справочник программиста метаассемблера Sperry Univac Computer Systems (MASM) (PDF) . Архивировано (PDF) из оригинала 9 октября 2022 г. Проверено 7 июня 2020 г.
  19. ^ «Как использовать встроенный язык ассемблера в коде C» . gnu.org . Проверено 5 ноября 2020 г.
  20. ^ abcd Саломон, Дэвид (февраль 1993 г.) [1992]. Написано в Университете штата Калифорния, Нортридж, Калифорния, США. Чиверс, Ян Д. (ред.). Сборщики и грузчики (PDF) . Серия Эллиса Хорвуда «Компьютеры и их приложения» (1-е изд.). Чичестер, Западный Суссекс, Великобритания: Ellis Horwood Limited / Simon & Schuster International Group . стр. 7, 237–238. ISBN 0-13-052564-2. Архивировано (PDF) из оригинала 23 марта 2020 г. Проверено 1 октября 2008 г.(xiv+294+4 страницы)
  21. ^ Финлейсон, Ян; Дэвис, Брэндон; Гэвин, Питер; Э-э, Ган-Рён; Уолли, Дэвид; Сьеландер, Магнус; Тайсон, Гэри (2013). «Повышение эффективности процессора за счет статической конвейерной обработки инструкций». Материалы 14-й конференции ACM SIGPLAN/SIGBED «Языки, компиляторы и инструменты для встраиваемых систем» . стр. 33–44. дои : 10.1145/2465554.2465559. ISBN 9781450320856. S2CID  8015812.
  22. ^ Бек, Леланд Л. (1996). «2». Системное программное обеспечение: введение в системное программирование . Эддисон Уэсли .
  23. ^ Аб Хайд, Рэндалл (сентябрь 2003 г.) [1996-09-30]. «Предисловие («Зачем кому-то изучать это?») / Глава 12 – Классы и объекты». Искусство языка ассемблера (2-е изд.). Пресс без крахмала . ISBN 1-886411-97-2. Архивировано из оригинала 6 мая 2010 г. Проверено 22 июня 2020 г.Ошибки: [1] (928 страниц) [2][3]
  24. ^ abcd Руководство разработчика программного обеспечения для архитектуры Intel, том 2: Справочник по набору инструкций (PDF) . Том. 2. Корпорация Интел . 1999. Архивировано из оригинала (PDF) 11 июня 2009 г. Проверено 18 ноября 2010 г.
  25. ^ Феррари, Адам; Бэтсон, Алан; Недостаток, Майк; Джонс, Анита (19 ноября 2018 г.) [весна 2006 г.]. Эванс, Дэвид (ред.). «Руководство по сборке x86». Информатика CS216: Представление программ и данных. Университет Вирджинии . Архивировано из оригинала 24 марта 2020 г. Проверено 18 ноября 2010 г.
  26. ^ «Руководство по архитектуре SPARC, версия 8» (PDF) . СПАРК Интернэшнл . 1992. Архивировано из оригинала (PDF) 10 декабря 2011 г. Проверено 10 декабря 2011 г.
  27. ^ Моксэм, Джеймс (1996). «Интерпретатор ZINT Z80». Коды операций Z80 для ZINT . Архивировано из оригинала 24 марта 2020 г. Проверено 21 июля 2013 г.
  28. ^ Хайд, Рэндалл . «Глава 8. MASM: Директивы и псевдокоды операций» (PDF) . Искусство компьютерного программирования . Архивировано (PDF) из оригинала 24 марта 2020 г. Проверено 19 марта 2011 г.
  29. ^ Система автокодера 1401, программа № 1401-AU-037, версия 3, уровень модификации 11 (PDF) . 07.12.1965 . Проверено 21 января 2024 г. Следующее незначительное ограничение или ограничение действует в отношении использования автокодера 1401 при кодировании макроинструкций...
  30. ^ Грисволд, Ральф Э. (1972). "Глава 1". Макрореализация SNOBOL4 . Сан-Франциско, Калифорния, США: WH Freeman and Company . ISBN 0-7167-0447-1.
  31. ^ «Макросы (C/C++), библиотека MSDN для Visual Studio 2008». Корпорация Microsoft, 16 ноября 2012 г. Архивировано из оригинала 24 марта 2020 г. Проверено 22 июня 2010 г.
  32. ^ Кесслер, Марвин М. (18 декабря 1970 г.). «*Концептуальный* отчет 14. Реализация макросов для структурированного программирования в OS/360». Программное обеспечение MVS: Концепция 14 макросов . Гейтерсбург, Мэриленд, США: Международная корпорация Business Machines . Архивировано из оригинала 24 марта 2020 г. Проверено 25 мая 2009 г.
  33. ^ «Функция набора инструментов ассемблера высокого уровня повышает производительность программиста» . Информационные письма . ИБМ . 12 декабря 1995 г. А95-1432. Архивировано из оригинала 07 марта 2023 г.
  34. ^ Whitesmiths Ltd (15 июля 1980 г.). Справочное руководство по естественному языку.
  35. ^ «Язык ассемблера: определение и многое другое с сайта Answers.com» . ответы.com . Архивировано из оригинала 8 июня 2009 г. Проверено 19 июня 2008 г.
  36. ^ Провинчиано, Брайан (17 апреля 2005 г.). «NESHLA: ассемблер 6502 высокого уровня с открытым исходным кодом для развлекательной системы Nintendo». Архивировано из оригинала 24 марта 2020 г. Проверено 24 марта 2020 г.
  37. ^ Дюфрен, Стивен (21 августа 2018 г.). «Кэтлин Бут: сборка первых компьютеров и изобретение сборки». Архивировано из оригинала 24 марта 2020 г. Проверено 10 февраля 2019 г.
  38. ^ Аб Бут, Эндрю Дональд ; Бриттен, Кэтлин Хильда Валери (сентябрь 1947 г.) [август 1947 г.]. Общие соображения по проектированию универсального электронного цифрового компьютера (PDF) (2-е изд.). Институт перспективных исследований, Принстон, Нью-Джерси, США: Колледж Биркбек, Лондон . Архивировано (PDF) из оригинала 24 марта 2020 г. Проверено 10 февраля 2019 г. Неоригинальные идеи, содержащиеся в следующем тексте, были получены из ряда источников... Однако считается, что следует выразить признательность профессору Джону фон Нейману и доктору Герману Гольдштейну за многие плодотворные действия. дискуссии...
  39. ^ Кэмпбелл-Келли, Мартин (апрель 1982 г.). «Развитие компьютерного программирования в Великобритании (1945–1955 гг.)». IEEE Анналы истории вычислений . 4 (2): 121–139. дои : 10.1109/MAHC.1982.10016. S2CID  14861159.
  40. ^ Кэмпбелл-Келли, Мартин (1980). «Программирование EDSAC: раннее программирование в Кембриджском университете». IEEE Анналы истории вычислений . 2 (1): 7–36. дои : 10.1109/MAHC.1980.10009.
  41. ^ "Премия пионера компьютеров 1985 года 'За программирование на ассемблере' Дэвида Уилера" . 27 марта 2018 г.
  42. ^ Уилкс, Морис Винсент (1949). «EDSAC – электронная вычислительная машина». Журнал научных инструментов . 26 (12): 385–391. Бибкод : 1949JScI...26..385W. дои : 10.1088/0950-7671/26/12/301.
  43. ^ да Круз, Фрэнк (17 мая 2019 г.). «Калькулятор магнитного барабана IBM 650». История вычислений - хронология вычислений. Колумбийский университет . Архивировано из оригинала 15 февраля 2020 г. Проверено 17 января 2012 г.
  44. ^ Коллен, Моррис Ф. (март – апрель 1994 г.). «Истоки информатики». Журнал Американской ассоциации медицинской информатики . 1 (2): 96–97. дои : 10.1136/jamia.1994.95236152. ПМК 116189 . ПМИД  7719803. 
  45. ^ Петтус, Сэм (10 января 2008 г.). «SegaBase Том 6 — Сатурн». Архивировано из оригинала 13 июля 2008 г. Проверено 25 июля 2008 г.{{cite web}}: CS1 maint: неподходящий URL ( ссылка )
  46. ^ Каулер, Барри (9 января 1997 г.). Язык ассемблера Windows и системное программирование: 16- и 32-битное низкоуровневое программирование для ПК и Windows. ЦРК Пресс . ISBN 978-1-48227572-8. Проверено 24 марта 2020 г. Всегда бушуют споры о применимости языка ассемблера в современном мире программирования.
  47. ^ Се, Пол (24 марта 2020 г.) [2016, 1996]. «Оптимизация программирования». Архивировано из оригинала 24 марта 2020 г. Проверено 24 марта 2020 г. ... изменения в дизайне, как правило, влияют на производительность больше, чем... не следует сразу переходить к ассемблеру до тех пор, пока...
  48. ^ "Индекс ТИОБЕ" . Программное обеспечение ТИОБЕ . Архивировано из оригинала 24 марта 2020 г. Проверено 24 марта 2020 г.
  49. ^ Руслинг, Дэвид А. (1999) [1996]. «Глава 2 Основы программного обеспечения». Ядро Linux . Архивировано из оригинала 24 марта 2020 г. Проверено 11 марта 2012 г.
  50. ^ аб Маркофф, Джон Грегори (28 ноября 2005 г.). «Написание самого быстрого кода вручную для развлечения: человеческий компьютер продолжает ускорять работу чипов». Нью-Йорк Таймс . Сиэтл, Вашингтон, США. Архивировано из оригинала 23 марта 2020 г. Проверено 4 марта 2010 г.
  51. ^ "Плохое битовое поле" . http://hardwarebug.org . 30 января 2010 г. Архивировано из оригинала 5 февраля 2010 г. Проверено 4 марта 2010 г.
  52. ^ «GCC устраивает беспорядок» . http://hardwarebug.org . 13 мая 2009 г. Архивировано из оригинала 16 марта 2010 г. Проверено 4 марта 2010 г.
  53. ^ Хайд, Рэндалл . «Большие дебаты». Архивировано из оригинала 16 июня 2008 г. Проверено 3 июля 2008 г.
  54. ^ «Источник кода снова терпит неудачу» . http://hardwarebug.org . 30 января 2010 г. Архивировано из оригинала 02 апреля 2010 г. Проверено 4 марта 2010 г.
  55. ^ Клик, Клифф; Гетц, Брайан. «Ускоренный курс современного оборудования». Архивировано из оригинала 24 марта 2020 г. Проверено 1 мая 2014 г.
  56. ^ «Программирование 68K в Fargo II» . Архивировано из оригинала 2 июля 2008 г. Проверено 3 июля 2008 г.
  57. ^ "Бенчмарк BLAS, август 2008 г." . eigen.tuxfamily.org. 01 августа 2008 г. Архивировано из оригинала 24 марта 2020 г. Проверено 4 марта 2010 г.
  58. ^ "x264.git/common/x86/dct-32.asm". git.videolan.org. 29 сентября 2010 г. Архивировано из оригинала 4 марта 2012 г. Проверено 29 сентября 2010 г.
  59. ^ "rav1e/README.md в версии 0.6.3" . Гитхаб . Архивировано из оригинала 22 февраля 2023 г. Проверено 21 февраля 2023 г.
  60. ^ "README.md · 1.1.0 · VideoLAN / dav1d» . 13 февраля 2023 г. Архивировано из оригинала 22 февраля 2023 г. Проверено 21 февраля 2023 г.
  61. ^ Босворт, Эдвард (2016). «Глава 1 – Зачем изучать язык ассемблера». www.edwardbosworth.com . Архивировано из оригинала 24 марта 2020 г. Проверено 1 июня 2016 г.
  62. ^ «Инструкции по макросам DFSMS для z/OS версии 2, выпуска 3 для наборов данных» (PDF) . ИБМ. 15 февраля 2019 г. Архивировано (PDF) из оригинала 25 июня 2021 г. Проверено 14 сентября 2021 г.
  63. ^ Пол, Маттиас Р. (2001) [1996], «Спецификация и справочная документация для NECPINW», NECPINW.CPI - драйвер переключения кодовых страниц DOS для NEC Pinwriters (изд. 2.08), FILESPEC.TXT, NECPINW.ASM, EUROFONT. INC из NECPI208.ZIP, заархивировано из оригинала 10 сентября 2017 г. , получено 22 апреля 2013 г.
  64. ^ Пол, Матиас Р. (13 мая 2002 г.). «[fd-dev] mkeyb». freedos-dev . Архивировано из оригинала 10 сентября 2018 г. Проверено 10 сентября 2018 г.

дальнейшее чтение

Внешние ссылки