Машинный код

Материал из Википедии ? свободной энциклопедии
(перенаправлено с ≪ Машинная инструкция ≫)
Перейти к навигации Перейти к поиску
Памятка программиста, 1960-е годы. Цифровой (машинный) код ≪ Минск-22

Маши?нный код ( платфо?рменно-ориенти?рованный код ), маши?нный язы?к  ? система команд (набор кодов операций) конкретной вычислительной машины , которая интерпретируется непосредственно процессором или микропрограммами этой вычислительной машины. [1]

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

Каждая модель процессора имеет собственный набор команд, хотя во многих моделях эти наборы команд сильно перекрываются. Говорят, что процессор A совместим с процессором B , если процессор A полностью ≪понимает≫ машинный код процессора B . Если процессоры A и B имеют некоторое подмножество инструкций, по которым они взаимно совместимы, то говорят, что они одной ≪архитектуры≫ (имеют одинаковую архитектуру набора команд ).

Машинная инструкция

[ править | править код ]

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

Операции, записываемые в виде одной машинной инструкции, можно разделить на ≪простые≫ ( элементарные операции ) и ≪сложные≫. Кроме того, большинство современных процессоров состоит из отдельных ≪исполнительных устройств≫ ? вычислительных блоков, которые умеют исполнять лишь ограниченный набор простейших операций. При исполнении очередной инструкции специальный блок процессора ? декодер ? транслирует (декодирует) её в последовательность элементарных операций, понимаемых конкретными исполнительными устройствами.

Архитектура набора команд процессора определяет, какие операции он способен выполнять, и какой машинной инструкции какие числовые коды операций (опкоды) соответствуют. Опкоды бывают постоянной длины (у RISC -, MISC -архитектур) и диапазонной (у CISC -архитектур; например: для архитектуры x86 команда имеет длину от 8 до 120 битов).

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

Машинный код как язык программирования

[ править | править код ]

Машинный код можно рассматривать как примитивный язык программирования или как самый низкий уровень представления скомпилированных или ассемблированных компьютерных программ. Хотя вполне возможно создавать программы прямо в машинном коде, сейчас это делается редко в силу громоздкости кода и трудоёмкости ручного управления ресурсами процессора, за исключением ситуаций, когда требуется экстремальная оптимизация . Поэтому подавляющее большинство программ пишется на языках более высокого уровня и транслируется в машинный код компиляторами . Машинный код иногда называют нативным кодом (также собственным или родным кодом  ? от англ.   native code ), когда говорят о платформенно-зависимых частях языка или библиотек. [2]

Программы на интерпретируемых языках (таких как Basic или Python ) не транслируются в машинный код; вместо этого они либо исполняются непосредственно интерпретатором языка, либо транслируются в псевдокод ( байт-код ). Однако интерпретаторы этих языков (которые сами можно рассматривать как процессоры), как правило, представлены в машинном коде.

В некоторых компьютерных архитектурах поддержка машинного кода реализуется ещё более низкоуровневым слоем программ, называемых микропрограммами . Это позволяет обеспечить единый интерфейс машинного языка у всей линейки или семейства компьютеров, которые могут иметь значительные структурные отличия между собой, и облегчает перенос программ в машинном коде между разными моделями компьютеров. Примером такого подхода является семейство компьютеров IBM System/360 и их преемников: несмотря на разные шины шириной от 8 до 64 бит и выше, тем не менее, у них общая архитектура на уровне машинного языка.

Использование слоя микрокода для реализации эмулятора позволяет компьютеру представлять архитектуру совершенно другого компьютера. В линейке System/360 это использовалось для переноса программ с более ранних машин IBM на новое семейство ? например, эмулятор IBM 1401/1440/1460 на IBM S/360 model 40.

Абсолютный и позиционно-независимый код

[ править | править код ]

Абсолютный код ( англ.   absolute code ) ? программный код, пригодный для прямого выполнения процессором [1] , то есть код, не требующий дополнительной обработки (например, разрешения ссылок между различными частями кода или привязки к адресам в памяти, обычно выполняемой загрузчиком программ ). Примерами абсолютного кода являются исполнимые файлы в формате .COM и загрузчик ОС, располагаемый в MBR . Часто абсолютный код понимается в более узком смысле как позиционно-зависимый код (то есть код, привязанный к определённым адресам памяти).

Позиционно-независимый код ( англ.   position-independent code ) ? программа, которая может быть размещена в любой области памяти, так как все ссылки на ячейки памяти в ней относительные (например, относительно счётчика команд ). Такую программу можно переместить в другую область памяти в любой момент, в отличие от перемещаемой программы , которая хотя и может быть загружена в любую область памяти, но после загрузки должна оставаться на том же месте. [1]

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

Программа ≪Hello, world!≫

[ править | править код ]

Программа ≪ Hello, world! ≫ для процессора архитектуры x86 (ОС MS DOS , вывод при помощи BIOS прерывания int 10h) выглядит следующим образом (в шестнадцатеричном представлении):

BB 11 01 B9 0D 00 B4 0E 8A 07 43 CD 10 E2 F9 CD 20 48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21

Данная программа работает при её размещении по смещению 100 16 . Отдельные инструкции выделены цветом:

  • BB 11 01 , B9 0D 00 , B4 0E , 8A 07  ? команды присвоения значений регистрам.
  • 43  ? инкремент регистра BX.
  • CD 10 , CD 20  ? вызов программных прерываний 10 16 и 20 16 .
  • E2 F9  ? команда для организации цикла.
  • Малиновым показаны данные (строка ≪Hello, world!≫).

Тот же код ассемблерными командами :

XXXX:0100 
    mov     bx, 0111h
       ; поместить в bx смещение строки HW
XXXX:0103 
    mov     cx, 000Dh
       ; поместить в cx длину строки HW
XXXX:0106 
    mov     ah, 0Eh
         ; поместить в ah номер функции прерывания 10h
XXXX:0108 
    mov     al, [bx]
        ; поместить в al значение ячейки памяти, адрес которой находится в bx
XXXX:010A 
    inc     bx
              ; перейти к следующему байту строки (увеличить смещение на 1)
XXXX:010B 
    int     10h
             ; вызов прерывания 10h
XXXX:010D 
    loop    0108
            ; уменьшить cx на 1 и, если результат≠0, то перейти по адресу 0108
XXXX:010F 
    int     20h
             ; прерывание 20h: завершить программу
XXXX:0111 
HW  db      'Hello, World!'
 ; строка, которую требуется напечатать

Примечания

[ править | править код ]
  1. 1 2 3 Толковый словарь по вычислительным системам = Dictionary of Computing / Под ред. В. Иллингуорта и др.: Пер. с англ. А. К. Белоцкого и др.; Под ред. Е. К. Масловского. ? М. : Машиностроение, 1990. ? 560 с. ? 70 000 (доп.) экз.  ? ISBN 5-217-00617-X (СССР), ISBN 0-19-853913-4 (Великобритания).
  2. Kate Gregory. Managed, Unmanaged, Native: What Kind of Code Is This? (28 апреля 2003). Дата обращения: 27 марта 2012. Архивировано 30 мая 2012 года.