Код складання проти коду машини проти коду об’єкта?


227

Яка різниця між об'єктним кодом, машинним кодом та кодом складання?

Чи можете ви навести наочний приклад їх різниці?


Мені також цікаво, звідки взялася назва "об'єктного коду"? Що в ній має означати слово «об’єкт»? Це якось пов’язано з об’єктно-орієнтованим програмуванням або просто збігом імен?
SasQ


Я не запитую про те, що таке об'єктний код, капітане Очевидний. Я запитую про те, звідки пішла назва і чому її називають "об'єктним" кодом.
BarbaraKwarc

Відповіді:


296

Машинний код - це двійковий (1 і 0) код, який може виконуватися безпосередньо процесором. Якби ви відкривали файл машинного коду в текстовому редакторі, ви побачили б сміття, включаючи недруковані символи (ні, не ті недруковані символи;)).

Об'єктний код - це частина машинного коду, яка ще не пов'язана з повною програмою. Саме машинний код для однієї конкретної бібліотеки чи модуля буде складати готовий продукт. Він також може містити заповнювачі або компенсації, не знайдені в машинному коді завершеної програми. Компоновщик буде використовувати ці наповнювачі та корекції для підключення все разом.

Код складання - це текстовий і (дещо) вихідний код, який читається людиною, який має здебільшого прямий аналог 1: 1 з інструкціями на машині. Це здійснюється за допомогою мнемоніки для фактичних інструкцій, регістрів чи інших ресурсів. Приклади включають в себе JMPі MULTінструкції стрибкової і множення цього процесора. На відміну від машинного коду, процесор не розуміє код складання. Ви перетворюєте код складання в машину за допомогою асемблера або компілятора , хоча ми зазвичай думаємо про компілятори в поєднанні з мовою програмування високого рівня, яка абстрагується далі від інструкцій процесора.

Побудова повноцінної програми передбачає написання вихідного коду для програми на зборах або на мові вищого рівня, як C ++. Вихідний код збирається (для збірного коду) або компілюється (для мов вищого рівня) для об'єктного коду, а окремі модулі з’єднуються разом, щоб стати машинним кодом для остаточної програми. Що стосується дуже простих програм, то крок зв’язування може не знадобитися. В інших випадках, таких як IDE (інтегрована середовище розробки), лінкер і компілятор можуть викликатися разом. В інших випадках може бути використаний складний файл створення сценарію чи рішення, щоб розповісти середовищу, як скласти остаточну програму.

Існують також інтерпретовані мови, які поводяться по-різному. Інтерпретовані мови покладаються на машинний код спеціальної програми перекладача. На базовому рівні перекладач аналізує вихідний код і негайно перетворює команди на новий машинний код та виконує їх. Сучасні перекладачі, які іноді також називають середовищем виконання або віртуальною машиною , набагато складніші: оцінюючи за один раз цілі розділи вихідного коду, кешуючи та оптимізуючи, де це можливо, та обробляти складні завдання управління пам'яттю. Інтерпретована мова також може бути попередньо складена до проміжного мови нижнього рівня або байтового коду, подібно до коду складання.


24
+1: приємна, але дещо спрощена відповідь - не всі вказівки зі збірки переводяться 1: 1 на машинні інструкції, а файли об’єктів можуть містити й інші дані (інформація про переїзд, таблиці символів, ...)
Крістоф

5
До вашого першого випуску було додано слово, яке було відредаговано, щоб зробити друге зрозумілішим.
Joel Coehoorn

2
@Christoph: ви говорите, "не всі інструкції зі збирання переведені 1: 1 на інструкції з машини", будь ласка, наведіть приклад.
Олоф Форшелл

5
@Olof: архітектури RISC іноді надають віртуальний набір інструкцій на рівні збірки - наприклад, псевдоінструкції MIPS ( en.wikipedia.org/wiki/MIPS_architecture#Pseudo_instructions )
Крістоф

3
@Panzercrisis асемблер нічого не додав. Це безпосередньо переклад того, що ви написали, на фактичні інструкції з машини. І я б не назвав додатковий код, який вводять компілятори, "непотрібним"
Joel Coehoorn

125

Інші відповіді дали хорошу характеристику різниці, але ви також попросили наочно. Ось схема, що показує, що вони проходять шлях від коду С до виконуваного файлу.


3
Я вважаю це дійсно корисним, але в ньому відсутня мітка "Код машини"
Alexx Roche

Отже, коли він знаходиться на рівні виконуваного коду, це еквівалент машинному коду?
CMCDragonkai

3
У контексті цієї діаграми "об'єктний код" - це машинний код.
Графіка Noob

5
Власне, і об'єктний, і виконуваний код є машинними кодами. різниця полягає в тому, що об'єктний код не є завершеною програмою. Її потрібно поєднувати з іншими кодами бібліотеки / модулів, як зазначено на схемі, щоб сформувати повну виконувану програму / код.
okey_on

@okeyxyz, на якому рівні було б правильно сказати, що це безпосередньо виконується процесором? Після асемблера, після лінкера, після навантажувача, після його перетворення в мікроконтролер?
Селерітас

49

Код складання - це читане людиною представлення машинного коду:

mov eax, 77
jmp anywhere

Машинний код - це чистий шістнадцятковий код:

5F 3A E3 F1

Я припускаю, що ви маєте на увазі код об'єкта як у файлі об'єкта. Це варіант машинного коду, з тією різницею, що стрибки на зразок параметризовані таким чином, що лінкер може заповнити їх.

Асемблер використовується для перетворення коду асемблери в машинний код (об'єктний код). Лінкер пов'язує декілька об'єктних (і бібліотечних) файлів для створення виконуваного файлу.

Я колись писав програму асемблера в чистому шістнадцятковому періоді (асемблер не доступний), на щастя, це було ще на старому доброму (стародавньому) 6502.


76
Ні, ні, ні. Машинний код - це не шістнадцятковий код. це чистий двійковий. Шістнадцятковий код - просто зручне подання двійкового.
Бретон

56
Якщо ми справді йдемо в крайнощі, це не бінарне, це кількість накопиченої електроенергії в ланцюзі. ;-)
Toon Krijthe

17
Так, звісно. Існує взаємозв'язок між шістнадцятковим числом і тим, що ви б назвали " машинним кодом ", але сказати, що "гексид" є машинним кодом , не зовсім точно . Це все, що я намагаюся сказати.
Бретон

9
@Breton У цьому сенсі не існує такого поняття, як "шістнадцятковий код", правда? "Шістнадцятковий код" - це лише спосіб перегляду машинного коду. Ви можете переглядати машинний код у шістнадцятковій, двійковій, восьмеричній, десятковій або як завгодно. Також у цьому сенсі також немає "бінарного коду". Знову ж таки, "двійковий код" - це лише спосіб перегляду машинного коду.
Утку

9
@Breton Те, що ви говорите, насправді не має особливого сенсу. Бінарне - це спосіб представлення, як і шестигранний. Якщо він не шістнадцятковий, він також не є двійковим.
Корай Тугай

18

8B 5D 32 це машинний код

mov ebx, [ebp+32h] це складання

lmylib.soмістить 8B 5D 32об'єктний код


8

Ще не згадуваний момент - це кілька різних типів коду складання. У найосновнішій формі всі числа, що використовуються в інструкціях, повинні бути вказані як константи. Наприклад:

$ 1902: BD 37 14: LDA $ 1437, X
1905 $: 85 03: STA $ 03
1907 $: 85 09: STA $ 09
$ 1909: CA: DEX
$ 190A: 10: BPL $ 1902

Вищенаведений біт коду, якщо він зберігається за адресою 1900 доларів у картриджі Atari 2600, відображатиме ряд рядків у різних кольорах, зібраних із таблиці, що починається з адреси 1437 доларів. На деяких інструментах введення адреси разом з крайньою правою частиною рядка вгорі зберігатиме для пам’яті значення, показані в середньому стовпці, і починає наступний рядок із наступної адреси. Вводити код у цій формі було набагато зручніше, ніж вводити шістнадцятку, але треба було знати точні адреси всього.

Більшість асемблерів дозволяють використовувати символічні адреси. Наведений вище код буде написаний більше як:

rainbow_lp:
  lda ColorTbl, х
  ста WSYNC
  ста КОЛУБК
  декс
  bpl rainbow_lp

Асемблер автоматично відрегулює інструкцію LDA, щоб він посилався на будь-яку адресу, відображену на ярлику ColorTbl. Використання цього стилю асемблера набагато простіше писати та редагувати код, ніж це було б можливо, якби довелося вводити вручну та підтримувати всі адреси.


1
+1. Ще один додатковий момент: також існують різні синтаксиси мови збірки , найвідоміші - Intel та AT&T .
informatik01

1
@ informatik01: Як щодо Intel 8080 мнемоніка проти Zilog Z80? Я б здогадався, що це передувало синтаксичній війні Intel проти AT&T.
supercat

Не сперечаючись, я щойно згадував цей аспект (різний синтаксис) і наводив приклад двох найпопулярніших / добре відомих / відомих синтаксисів.
informatik01

4

Вихідний код, код складання, машинний код, код об'єкта, байт-код, виконуваний файл та файл бібліотеки.

Усі ці терміни часто дуже бентежать для більшості людей через те, що вони думають, що вони взаємовиключні . Дивіться схему, щоб зрозуміти їх відносини. Опис кожного терміна наведено нижче.


Типи коду


Вихідний код

Інструкції з легкої для читання (програмування) мови


Код високого рівня

Інструкції, написані мовою високого рівня (програмування),
наприклад, програмами C, C ++ та Java


Код складання

Інструкції, написані мовою складання (різновид мови програмування низького рівня). Як перший крок процесу компіляції, код високого рівня перетворюється в цю форму. Це код складання, який потім перетворюється на фактичний машинний код. У більшості систем ці два етапи виконуються автоматично як частина компіляційного процесу.
наприклад, program.asm


Код об'єкта

Продукт процесу компіляції. Він може бути у вигляді машинного коду або байтового коду.
наприклад, file.o


Машинний код

Інструкції з машинної мови.
наприклад, a.out


Байт-код

Інструкція в проміжному вигляді, яку може виконати перекладач, такий як JVM.
наприклад, файл класу Java


Виконаний файл

Продукт зв’язування процесу. Вони є машинним кодом, який може бути безпосередньо виконаний процесором.
наприклад, файл .exe.

Зауважте, що в деяких контекстах файл, що містить байт-код або інструкції з мов скриптів, також може вважатися виконаним.


Файл бібліотеки

Деякий код компілюється в цю форму з різних причин, таких як повторне використання та пізніше використовується виконуваними файлами.


1
Я заперечую, що не всі збори є справді джерелом у найсуворішому сенсі коду, написаного та / або підтримуваного людьми. Часто він створюється машиною з джерела, і ніколи не призначений для споживання людиною (наприклад, gcc дійсно створює текст asm, який він подає в окремий асемблер, замість того, щоб мати вбудований асемблер всередині cc1виконуваного файлу). Я думаю, що коло асфальту повинно простягати ліву частину кола "джерело", тому що деякий асм - це лише асм, а не джерело. Звичайно, це ніколи не об'єктний код, але деякий ASM - це крок на шляху від джерела до об'єктних файлів.
Пітер Кордес

@PeterCordes Дякую за коментар. Мені не було відомо, що ви сказали про роботу gcc. Однак я боюся, якщо зможу повністю з вами погодитися. Я маю на увазі, що вихідний код - це те, що написано за допомогою читаної людиною мови програмування. Це може бути, а може і не писатися або підтримуватися людьми. Я впевнений, що вам будуть відомі транскопілятори. З вашої точки зору, до якої категорії ви поставите продукт такого компілятора? Вихідний код чи щось інше? Будь ласка, виправте мене, якщо я помиляюся. Подальші коментарі завжди вітаються.
Бертрам Гілфойл

1

Код складання обговорюється тут .

"Мова збірки - це мова низького рівня для програмування комп'ютерів. Він реалізує символічне зображення числових машинних кодів та інших констант, необхідних для програмування певної архітектури процесора."

Тут розглядається машинний код .

"Код машини або мова машини - це система інструкцій та даних, що виконуються безпосередньо центральним процесорним блоком комп'ютера."

В основному, код асемблера - це мова, і він перекладається на об'єктний код (власний код, який працює центральний процесор) асемблером (аналогічним компілятору).


1

Я думаю, що це основні відмінності

  • читабельність коду
  • контроль над тим, що робить ваш код

Читання може зробити код поліпшеним або заміненим через 6 місяців після його створення з літними зусиллями. швидше виконання.

Сьогодні комп'ютери IMO досить швидкі, щоб програміст міг швидко виконувати програму OOP.


1

Збірка - це короткий описовий термін, який люди можуть зрозуміти, що їх можна безпосередньо перевести в машинний код, який фактично використовує процесор.

Незважаючи на те, що людина дещо зрозуміла, Ассемблер все ще низький. Щоб зробити щось корисне, потрібно багато коду.

Тому замість цього ми використовуємо мови вищого рівня, такі як C, BASIC, FORTAN (ОК, я знаю, що я датувався). При компілюванні вони виробляють об'єктний код. Ранні мови мали машинну мову як їх об'єктний код.

У багатьох мовах сьогодні такі JAVA і C # зазвичай компілюються в байт-код, який не є машинним кодом, а тим, який легко інтерпретувати під час виконання для створення машинного коду.


Ваш коментар щодо Java та C # - обидва використовують компіляцію Just In Time, щоб байткоди не інтерпретувалися. C # (.NET в цілому) компілюється в Intermediate Language (IL), який потім JITed на рідній машинній мові для цільового процесора.
Craig Shearer

-1

Вихідні файли ваших програм компілюються в об'єктивні файли, а потім лінкер пов'язує ці об’єктні файли разом, створюючи виконуваний файл, включаючи машинні коди вашої архітектури.

І об'єктний, і виконуваний файл включає машинний код архітектури у вигляді друкованих та недрукувальних символів, коли він відкривається текстовим редактором.

Тим не менш, дихотомія між файлами полягає в тому, що об'єктні файли можуть містити невирішені зовнішні посилання (наприклад printf, наприклад). Отже, може знадобитися зв’язати його з іншими файлами об'єктів .. Тобто невирішені зовнішні посилання потрібні для вирішення, щоб отримати гідний виконуваний виконуваний файл, зв’язавшись з іншими об’єктними файлами, такими як бібліотека часу виконання C / C ++ .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.