Машинен код е компютърна програма, записана на нивото на машинен език, предназначена да бъде директно изпълнявана от процесора. Той използва набора от инструкции на определена компютърна архитектура и обикновено се представя като поредица от байтове (често показвани в двоичен код или в шестнадесетична форма). Машинният код е най-ниското ниво на софтуера и е зависим от хардуера: инструкции, кодирани за една архитектура, обикновено не работят на друга. Всички по-високо ниво езици се превеждат на машинен код (чрез асемблер, компилатор или JIT) или се интерпретират от софтуер, за да може процесорът да ги изпълнява.
Как е устроена една инструкция
Инструкцията указва на процесора каква операция да извърши. Всяка инструкция обикновено се състои от два основни компонента:
- опкод (код на операцията) — частта, която казва „какво“ да се направи (например добавяне, преместване, скок); този елемент е описван и в опкод.
- операнд(и) — данните или адресите, върху които се извършва операцията; могат да бъдат регистри, адреси на паметта, непосредствени стойности (immediate) и т.н. (операнд).
Операндите и начините за адресиране (addressing modes) са част от спецификацията на набора от инструкции. Някои инструкции имат фиксирана дължина (типично за RISC архитектури), а други — променлива (често при CISC архитектури като x86).
Набор от инструкции (ISA)
Наборът от инструкции (Instruction Set Architecture, ISA) е списък с всички опкодове и начина, по който те се кодират, какви типове операнди се поддържат и какво представлява програмният модел на процесора (регистри, адресно пространство, режимите на изпълнение). Този набор определя границите на това, което софтуерът може да прави директно с хардуера.
От асемблер и други езици до машинен код
Създателите на програми използват асемблерни програми (за ръчно писане на инструкции в удобна текстова форма) или компилатори (за автоматичен превод от език на по-високо ниво) да превърнат кода в машинен код. Компилират или асемблират се асемблерният код и други езици за програмиране, за да се получи изпълним двоичен файл, който може да бъде зареден и стартиран от операционната система.
Машинният код понякога се нарича роден код, защото е специфичен за дадената архитектура и работи „родно“ върху нея. Тази зависимост от хардуера означава, че един и същи двоичен файл не е преносим между различни ISA без рекомпилация или емулация.
Представяне и формати
- В паметта машинният код е просто последователност от байтове. За хората тези байтове често се показват в шестнадесетичен вид или като мнемонични инструкции чрез асемблер/дизасемблер.
- Изпълнимите файлове обикновено имат формати (например ELF, PE, Mach-O), които съдържат допълнителна структура: заглавия, таблици с адреси, символи, секции за данни и код и др.
- Ендийнсът (big-endian vs little-endian) и размерът на думата (word size, например 32- или 64-бита) влияят на това как данните и инструкциите се интерпретират от процесора.
Особености и практически бележки
- Някои процесори използват микрокод — вътрешен слой под машинния код — който превежда сложни инструкции в по-прости вътрешни операции.
- Режимът на изпълнение и защитните механизми (например NX/DEP — non-executable memory) контролират къде в паметта може да бъде изпълнен машинен код, което е важно за сигурността.
- Софтуерни инструменти като асемблери, дизасемблери и дебъгъри (debuggers) се използват за създаване, анализ и диагностика на машинен код.
- Има примерни техники като само-изместващ се код (self-modifying code) и големи оптимизации от компилаторите, които могат да генерират много сложен машинен код.
Машинен код срещу байткод и интерпретиран код
За разлика от машинния код, който е директно изпълним от процесора, някои среди използват междинни формати (например байткод при Java или .NET), които се изпълняват от виртуална машина или се превеждат динамично (JIT) в машинен код по време на изпълнение. Това дава по-голяма преносимост, но често с някаква цената по отношение на производителността спрямо родния машинен код.
Накратко: машинен код е най-ниското, хардуерно-специфично представяне на програма — низ от опкодове и операнди, които процесорът изпълнява. Разбирането на неговата структура и функциониране е ключово за работа с ниско-нивови технологии, оптимизация, отстраняване на грешки и сигурност.

