Машинный язык

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

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

Программы на машинном языке обычно не создаются непосредственно программистом , а с использованием языка программирования высокого уровня или ассемблера , а машинный код создается только с помощью компилятора или ассемблера . Когда говорят о «программировании на машинном языке», это иногда неправильно относится к программированию на ассемблере. С другой стороны, в случае выполнения интерпретатором машинные команды генерируются при запуске программы или во время выполнения.

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

  • Для типизирующего обозначения кода используется как определение синтаксиса. Пример: «Исходный код (для языка программирования XYZ)»
  • Для программного кода конкретной программы. Пример «двоичный код (для программы ABC)»

Машинная программа

«Машинная программа», контексты терминов и синонимов, встречающиеся в лингвистическом употреблении.

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

В Windows исполняемые файлы можно найти в файлах с расширением «.exe» . Во многих других операционных системах исполняемые файлы также управляются без расширения файла и в других форматах. Иногда их называют по-разному, например Б. под z / OS в качестве загрузочного модуля . Во многих встроенных системах или микроконтроллерах определенные машинные программы постоянно находятся в ПЗУ, например Б. загрузчик

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

Отличия от языка ассемблера

Программа в машинном коде состоит из последовательности байтов, которые представляют как команды, так и данные. Поскольку этот код трудно читать людям, команды на языке ассемблера представлены более понятными сокращениями, так называемыми мнемониками . Код операции, исходное и целевое поля, а также другая информация в командах может быть отмечена символическими идентификаторами (такими как MOVE, ZIP, LENGTH), возможно, дополненными числовыми значениями, например Б. для индивидуальной спецификации длины, номеров регистров и т. Д.

Формат файла
Как это обычно бывает с исходными текстами , программа на ассемблере обычно доступна в виде текстового файла , а машинная программа обычно сохраняется в виде двоичного файла.
инструкции
Программирование в текстовом формате с последующим переводом в машинный код ассемблером позволяет программисту создавать программы намного быстрее и проще, чем кодирование в машинном коде. Как правило, инструкция ассемблера соответствует ровно одной инструкции в машинном коде, за исключением макроассемблеров , которые могут генерировать несколько машинных инструкций из одной инструкции.
Форматы символов
Общие ассемблеры позволяют программисту кодировать символы и числа в различных форматах кода (текстовый, десятичный, шестнадцатеричный, восьмеричный, двоичный) и устанавливать их в машинной инструкции в формате, соответствующем инструкции. Пример: спецификации исходного текста 'A' или 'X'C1' 'или' B'11000001 '' (в коде EBCDIC ) означают одно и то же и становятся X'C1 'в машинном коде, что для команд для двойных операций имеет значение +193, соответствует букве «А» для символьных операций.
Объявление данных
Ассемблер позволяет программисту идентифицировать и называть поля данных как таковые, объявлять их в различных форматах и ​​давать им символические имена. В сгенерированном машинном коде пространство памяти резервируется в соответствии с этой информацией и (в случае констант ) предварительно назначается содержимым. В сгенерированных машинных командах символический адрес заменяется числовым адресом и используется длина определенных полей.
обращаясь
Ассемблер позволяет именовать места хранения данных и команд символически, так что программисту не нужно знать их числовые адреса. Адреса памяти указываются непосредственно на машинном языке. Даже при небольшом изменении программы адреса всех последующих частей программы будут смещены, что (при программировании на машинном языке) потребует адаптации всех этих адресов. Символьная адресация означает, что подпрограммы также могут вызываться на языке ассемблера , фактический адрес которого используется только в машинном коде ассемблером или компоновщиком .
Объем программы
Программа на ассемблере обычно связана с одной (1) определенной задачей и не зависит от других программ во время сборки. Используя такие методы, как «связывание» , в зависимости от платформы разработки, результаты нескольких сборок (например, называемых объектными модулями ) могут быть «объединены», что в целом приводит к машинной программе.
документация
Ассемблер позволяет добавлять к программе комментарии и дополнительную документацию. Как правило, эти части исходного кода не передаются в машинную программу.

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

Создание программы

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

  • Прямой ввод двоичного кода (чрезвычайно громоздкий и подверженный ошибкам, редко встречается с 1950-х годов)
  • Для того, чтобы написать числовой код в опкодах с использованием в шестнадцатеричный редакторе . (склонен к ошибкам)
  • С помощью ассемблера : языки ассемблера формулируют команды процессора машинного кода в виде мнемоники в простом синтаксисе. Затем этот исходный текст преобразуется ассемблером в машинный код .
  • Программа пишется на языке высокого уровня , а затем транслируется (компилируется) в машинный код компилятором . На промежуточном этапе часто сначала создается объектный код .
  • В качестве альтернативы программы на языке высокого уровня также могут обрабатываться интерпретатором - либо после компиляции в промежуточный код, либо напрямую . Примером этого является язык программирования Java , промежуточный код которого (также называемый байт-кодом ) выполняется интерпретатором. Это делается прозрачно для пользователя, когда, например, в веб-браузере выполняется апплет . В дополнение к Java, все .NET языки, такие как C # , переводятся в промежуточный код , который затем переведен в соответствующий машинный язык с помощью JIT - компилятор во время выполнения внутри CLR .
  • В установке из программного обеспечения , включая операционную систему, это часто уже доступно в машинном коде для каждой платформы. Это избавляет пользователя от необходимости компилировать программу.

пример

Язык программирования C

В следующем исходном коде на языке программирования более высокого уровня C вычисляется сумма чисел 2 и 3 и возвращается результат:

int main() {
    int a = 2;
    int b = 3;
    int c = a + b;
    return c;
}

Такая программа, если бы она была скомпилирована для процессора x86 , могла бы привести к следующему машинному коду:

Машинный код
( шестнадцатеричный )
связанный код ассемблера связанный код C Объяснение
55
48 89 E5
push rbp

mov rbp, rsp

int main() { Безопасный регистр RBP в стеке и установка RBP на значение регистра RSP, указателя стека (не принадлежит фактическому вычислению). Эта подготовка необходима для того, чтобы иметь возможность хранить значения переменных a , b и c в стеке.
C7 45 FC 02 mov DWORD PTR [rbp-4], 2 int a = 2; Установите для переменной a , адресуемой регистром RBP, значение 2.
C7 45 F8 03 mov DWORD PTR [rbp-8], 3 int b = 3; Установите переменную b , адресуемую регистром RBP, в значение 3.
8B 45 F8
8B 55 FC
01 D0
89 45 F4
mov eax, DWORD PTR [rbp-8]

mov edx, DWORD PTR [rbp-4]
add eax, edx
mov DWORD PTR [rbp-12], eax

int c = a + b; Установите регистр EAX на значение переменной b .

Установите регистр EDX на значение переменной a .
Добавьте значение EDX к значению EAX.
Установите для переменной c, адресованной RBP, значение EAX.

8B 45 F4 mov eax, DWORD PTR [rbp-12] return c; Установите регистр EAX на значение переменной c . Поскольку регистр EAX уже содержит это значение, эту инструкцию можно было бы опустить в оптимизированной программе.
5D
C3
pop rbp

ret

} Верните RBP к исходному значению.

Вернитесь туда, где был вызван main . Регистр EAX содержит возвращаемое значение.

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

Машинный код на компьютерах IBM на примере OS / 390

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

Данных создается в соответствии с заданным форматом хранения. Значение «12» может, например, B. иметь следующий вид (шестнадцатеричное представление минимальной длины):

F1F2 Текст или номер без упаковки
012C упакованный позитив, хранение одного полубайта на число, в конце знаковый полубайт.
012D упакованный негатив (dto)
0C двоичный положительный, соответствует B'00001100 '

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

Эти команды состоят из кода команды и - в зависимости от команды - параметры различных структур. Следующие примеры показаны в шестнадцатеричном формате . Примеры команд:

C5.1C.92A4.8C2B (точки разделения вставлены только для лучшей читаемости):

C5 = Код команды для CLC = Логический символ сравнения; Сравнение персонажей
1C = длина минус 1 сравниваемых полей (с 00 сравнивается 1 байт и т. Д., Здесь 29 байтов)
92A4 = адрес первого операнда: 9 = базовый регистр, 2A4 = расстояние до регистра
8C2B = адрес второго операнда: 8 = базовый регистр, C2B = расстояние до регистра

47.80.B654:

47 = Код команды для BC = Переход по условию: Команда перехода, если выполняется условие (из предыдущей команды)
8 = состояние; здесь: если 'равно', мнемонический ассемблерный код BE (ветвление при равенстве)
0 = необязательный регистр, содержимое которого добавляется к адресу перехода; не на "0"
B = адрес назначения (базовый регистр)
654 = адрес назначения (расстояние); с содержимым B = 6C4410 произойдет переход к адресу 6C4A64.

<etc>

В коде ассемблера это кодирование могло бы, например, Б. выглядят так:

CLC FELDA (29), FIELDB
БЫТЬ ХХХ

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

ЕСЛИ Field_A = Field_B, то НАЙТИ XXX.

Если условие выполнено, выполняется переход к XXX (= реальный адрес 6C4A64), в противном случае машинный код <usw>продолжается с . Языки высокого уровня часто генерируют дополнительные команды, например Б. для выравнивания длин полей или форматов данных, загрузка регистров или вычисление адресов в массивах .

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

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

Для выполнения системных функций (таких как команды ввода / вывода , запрос даты / времени, ввод с клавиатуры, загрузка подпрограмм и т. Д.) Все, что требуется, - это системный вызов с командой 'SVC' (вызов супервизора) в машинной программе. . Выполняемая функция указывается во втором байте (см. Каталог); Дальнейшие параметры функции передаются через интерфейс данных, который определен в ее структуре и адрес которого указывается неявно согласованным регистром (не указанным в команде). Пример: X'05 08 '= ЗАГРУЗИТЬ, параметр = Pgm-Name и т. Д. Команды, выполняющие вызываемые функции, являются машинным кодом операционной системы. Они выполняются там, а затем возвращаются к команде, следующей за SVC.

Обзор типичных функций машинного языка

Набор инструкций

Следующие мнемоники (сокращения команд) были выбраны в качестве примера и зависят от языка ассемблера.

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

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

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

Пример: простая базовая команда, такая как SHL / SHR , которая сдвигает значение регистра на определенное количество разрядов влево или вправо, уже доступна в 8086. Более мощный вариант SHLD / SHRD , который также заполняет результирующие пробелы из другого целочисленного значения, реализован только с 80386 и далее.

Мощность: набор команд процессора предоставляет команды с разной функциональностью. Помимо простых, одноэтапных базовых операций, также доступны команды, объединяющие несколько операций в одной команде.

Примеры: Команда CMP (сравнение) позволяет сравнивать два значения для <,>, =. Команда XCHG (обмен) меняет местами два операнда. Команда CMPXCHG (сравнение и обмен) объединяет эти две команды и включает условный обмен данными в одной команде. В то время как команда BT (битовый тест) проверяет состояние только одного бита в целочисленном значении, команды BTC, BTR и BTS также позволяют установить проверяемый бит в зависимости от результата теста (BTS) , чтобы очистить его (BTR) или инвертировать (BTC) .

Общее различие делается между процессорами с набором команд RISC - ( компьютер с сокращенным набором команд ) или CISC - ( компьютер со сложным набором команд). Первые имеют значительно менее мощный набор инструкций, но обычно могут обрабатывать каждую отдельную инструкцию за один такт. Современные процессоры с набором инструкций CISC (которые сегодня почти полностью включают x86- совместимые процессоры) декодируют сложные инструкции CISC для более быстрой внутренней обработки на языке RISC-подобного микроконтроллера.

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

Категоризация команд

Базовые машинные команды можно разделить на следующие категории:

  • Арифметические операции: выполнение вычислений (ADD, ADC, SUB, SBB, DIV, MUL, INC, DEC)
  • Логические операции: логически связать битовые поля друг с другом ( AND , OR , XOR , NOT )
  • Бит-ориентированные операции: с их помощью можно адресовать отдельные биты в битовом поле, прочитать (BSF, BSR) , сдвинуть (SHL, SHR, RCL, RCR, ROL, ROR) или манипулировать (BT, BTC, BTR).
  • Операции с памятью: передача данных между регистрами процессора (MOV, MOVSX, MOVZX, XCHG) внутри регистра (BSWAP) , а также между регистрами и памятью
  • Операции сравнения: сравнение значений с использованием <,> и = (CMP, TEST)
  • Комбинированные команды из операций сравнения, арифметических операций и обмена данными (XADD, CMPXCHG)
  • Управляющие операции: ветви, влияющие на ход программы.
  • Преобразование данных: эти команды преобразуют значения из одного представления в другое, возможно, с убытком. Например: байт в слове (CBW) , длинное целое число в байте ( CVTLB ) или двойное точное число с плавающей запятой в целом числе ( CVTSD2SI ).

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

литература

  • Ассемблер - программирование на уровне машины с самого начала . Ророро в мягкой обложке № 61224 (2003), ISBN 3-499-61224-0 .

веб ссылки

Викисловарь: машинный язык  - объяснение значений, происхождение слов, синонимы, переводы

Индивидуальные доказательства

  1. Duden Computer Science . ISBN 3-411-05232-5 .
  2. машинный код . В: Gabler Wirtschaftslexikon
  3. Таблица кодов SVC для IBM MVS & OS / 390 & z / OS
  4. Инструкция по вызову супервизора в англоязычной Википедии