Чи можлива універсальна мова складання для всіх комп'ютерів?


23

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

Оскільки у нас існують різні комп'ютерні архітектури, чи це означає, що я повинен писати різний код в Асамблеї для різних архітектур? Якщо так, чому це не Асамблея, пишіть один раз - запускайте всюди тип мови? Не було б простіше просто зробити його універсальним, щоб ви написали його лише один раз і змогли запустити його практично на будь-якій машині з різною конфігурацією? (Я думаю, що це було б неможливо, але я хотів би отримати конкретні, поглиблені відповіді)

Деякі люди можуть сказати, що C - це мова, яку я шукаю. Я раніше не використовував C, але думаю, що це все ще мова високого рівня, хоча, ймовірно, швидше, ніж Java, наприклад. Я можу помилитися тут.


10
Які дослідження ви провели? Ми очікуємо, що ви зробите дослідження, перш ніж задавати питання, щоб допомогти вам поставити краще питання. На мові складання написано багато.
DW

4
Ми очікуємо, що ви зробите значну кількість досліджень / самонавчання, перш ніж задавати питання, і скажіть нам у питанні, яке дослідження ви зробили. У цьому випадку дослідження можуть включати читання відповідних статей у Вікіпедії (наприклад, про мову складання та архітектуру комп’ютера) та читання підручника з архітектури комп'ютера. Щоб зробити це кращим питанням: зробіть це дослідження, якщо ви ще цього не зробили, а потім відредагуйте питання, щоб пояснити проведене дослідження. Часто подібні дослідження допомагають сформулювати краще питання; і в будь-якому випадку це допомагає відповідачам уникати повторення того, що ви вже знаєте.
DW

15
Почніть з розуміння того, що / чому немає мови під назвою Асамблея.
Рафаель

2
одна "класична" проблема переносимості C - це різні розміри примітивів (наприклад, цілих чисел) на різних апаратних засобах;
vzn

3
Це скоріше соціальна проблема, ніж технічна - вам потрібно переконати всіх виробників процесорів змусити їхні процесори приймати ту саму машинну мову. (Насправді, x86 був майже таким, випадково - тоді смартфони зняли)
користувач253751

Відповіді:


45

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

Різні архітектури мають різні набори інструкцій: набір дозволених інструкцій різний для кожної архітектури. Таким чином, ви не можете сподіватися, що ви будете мати програму збирання один раз запустити всюди. Наприклад, набір інструкцій, підтримуваних процесорами x86, виглядає дуже відмінним від набору інструкцій, підтримуваних процесорами ARM. Якщо ви написали програму складання для процесора x86, вона мала б багато інструкцій, які не підтримуються на процесорі ARM, і навпаки.

Основна причина використання мови складання полягає в тому, що вона дозволяє дуже низько контролювати свою програму та скористатися всіма інструкціями процесора: налаштовуючи програму, щоб скористатися функціями, унікальними для конкретного процесора буде працювати далі, іноді ви можете пришвидшити програму. Філософія "писати один раз - всюди" принципово не суперечить цьому.


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

26
@nTuply Як тільки ви модифікуєте мову складання для обслуговування різних машин, вона стає мовою високого рівня з синтаксисом стилю монтажу. Після того, як ви вирішили використовувати мову високого рівня, ви можете також використовувати один з дружнішим синтаксисом і дозволити компілятору виконати важку роботу.
Девід Річербі,

15
Не зовсім дурна ідея мати "мову складання", що перекладається для різних машин, адже це в основному "ІК" LLVM. Однак з причин, які дає Девід, ти зазвичай не пишеш збірку LLVM. Також тому, що 99 разів із 100 ви б робили гіршу роботу, ніж писати це, ніж кланг перекладає свій C на LLVM. Мови складання є потенційно ефективнішими, ніж мови високого рівня, але в руках більшості фактичних програмістів з типовою кількістю часу, необхідної для оптимізації, вони все одно не досягають свого потенціалу.
Стів Джессоп

9
@nTuply, що існує. Процес переходу від цієї мови додаткової збірки до машинних інструкцій називається компіляцією.
Пол Дрейпер

3
@PJTraill Немає жодної причини писати компілятор в асемблері в сучасній системі, за винятком самого першого кроку завантаження (і в більшості випадків навіть тоді). Компілятори, написані мовою високого рівня, набагато більше шансів на те, що вони справді є реконструкційними. Порівняйте також. Як мова, чий компілятор написаний на C, коли-небудь може бути швидшою, ніж на C? . Мета компілятора полягає в перекладі з однієї мови (мови джерела) на іншу (зазвичай машинна мова для певної архітектури та ОС); це можна написати будь-якою мовою.
CVn

13

ВИЗНАЧЕННЯ мови складання полягає в тому, що це мова, яку можна перекласти безпосередньо в машинний код. Кожен код операції на мові збірки перекладається на точно одну операцію на цільовому комп'ютері. (Ну, це трохи складніше, ніж це: деякі асемблери автоматично визначають "режим адресації" на основі аргументів до оп-коду. Але все-таки принцип полягає в тому, що один рядок складання перекладається на одну машиномовну інструкцію.)

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

Ваше запитання трохи схоже на запитання: "Чи можна зробити човен, який не плаває, чи є інший спосіб подорожувати по воді, але має колеса та мотор і може подорожувати по суші?" Відповідь полягала б у тому, що за визначенням такий транспортний засіб не був би човном. Це звучить більше як машина.


1
C часто описували як "переносну мову складання".
Ларрі Гріц

2
@LarryGritz Звичайно. І коли C був винайдений, це було новаторським: він пропонував велику частину сили мови монтажу з легкістю використання зібраного. Але за визначенням, це все-таки складена мова
Джей

8

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

На практиці, однак, існують різні мікросхеми для різних цілей, з різними операціями та принципами проектування (наприклад, RISC проти CISC), які служать різним цілям, і набори інструкцій, які керують ними, і з цим мови монтажу відрізняються. Зрештою, відповідь така ж, як і на запитання, чому існує стільки різних мов програмування : різні цілі, різні дизайнерські рішення.

Зважаючи на це, ви, звичайно, можете ввести рівні абстракції, щоб потрапити на якийсь спільний інтерфейс. Наприклад, x86 закінчується на рівні чіпів протягом досить тривалого часу; є невеликий фрагмент обладнання, який переводить інструкції x86 на те, з чим реально працює ваш процесор . Такі мови, як C, були б ще одним кроком від апаратного забезпечення (якщо він, можливо, крихітний), аж до таких мов, як Haskell, Java або Ruby. Так, компілятор - одне з головних досягнень інформатики, оскільки вони дають змогу поділити проблеми таким чином.


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

Якщо під мовою складання ви маєте на увазі один, який забезпечує повний контроль над машинним кодом, згенерованим для певного типу (або сімейства) апаратних засобів, можна було б визначити одну мову "для всіх комп'ютерів" у нашому світі в даний момент, але це було б повинні продовжувати змінюватися. Це, мабуть, (якщо це добре розроблено) скоротить криву навчання для кодування нової архітектури, але я думаю, що будь-яка робота, яку ви хотіли б зробити з нею, а не компілятор, стосується лише крихітної частини архітектур. Що комп’ютери однакові на абстрактному рівні - це червона оселедець, мова йде про машинний код.
PJTraill

7

Ви згадуєте фразу "писати один раз запустити куди завгодно", не здаючись помітним її значення. Це маркетингове гасло для Sun Microsystems , комерційно винайдене для Java поняття "віртуальна машина" та "байт-коди" , хоча, можливо, ідея виникла в академічних колах 1- го. Пізніше ідея була скопійована Microsoft для .Net після того, як вони були успішно подані до суду за порушення порушення ліцензування Java. Байт-коди Java - це реалізація ідеї крос-машинної збірки або машинної мови. Вони використовуються для кількох інших мов, ніж Java, і теоретично їх можна використовувати для компіляції будь-якої мови. Після багатьох років дуже вдосконаленої оптимізації, Java наближається до продуктивності до складених мов, що показує, що мета високопродуктивних платформно-агностичних технологій віртуальної машини досяжна загалом.

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


8
Sun не винайшов ні віртуальні машини, ні байт-код, вони навіть не були першою групою, яка заробляла на них гроші. Знайдіть p-код.
jmoreno

@jmoreno: він також може захотіти шукати Smalltalk.
Боб Джарвіс - Відновіть Моніку

стаття не претендує на винайдене віртуальними машинами / байтовим кодом. є й інша історія, яка не цитується, але на яку згадується. btw ще одна ключова технологія, дуже актуальна тут: рідний клієнт google (функція chrome)
vzn

5

Причини високого рівня

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

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

Отже, у нас багато різних "ароматів" мікропроцесора, кожен зі своїми сильними і слабкими сторонами. Для всіх бажано використовувати сумісний набір інструкцій, оскільки це дозволяє повторно використовувати код і полегшує пошук людей з правильними навичками. Тим НЕ менше, набір команд робить впливає на вартість, складність, швидкість, простоту у використанні, а також фізичні обмеження процесора, і тому у нас є компроміс: є кілька «основних» набори команд (і багато незначні), і у кожному наборі інструкцій є багато процесорів з різними характеристиками.

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

Деталі обладнання

Напевно, найбільшим дизайнерським рішенням у наборі інструкцій є розмір слова , тобто те, наскільки велике число процесор може "природно" маніпулювати. 8-бітові процесори мають числа від 0-255, тоді як 32-бітні процесори мають числа від 0 до 4 294 967 295. Код, розроблений для одного, потрібно повністю переосмислити для іншого.

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

Існують і інші основні відмінності між наборами інструкцій. Більшість інструкцій поділяються на чотири категорії:

  • Обчислення (арифметичні та логічні)
  • Контрольний потік
  • Передача даних
  • Конфігурація процесора

Процесори відрізняються тим, які обчислення вони можуть виконувати, а також тим, як вони наближаються до потоку управління, передачі даних та конфігурації процесора.

Наприклад, деякі процесори AVR не можуть ні множити, ні ділити; тоді як всі процесори x86 можуть. Як ви можете уявити, усунення схеми, необхідної для таких завдань, як множення і ділення, може зробити процесор простішим і дешевшим; ці операції все ще можуть виконуватися за допомогою програмних процедур, якщо вони потрібні.

x86 дозволяє арифметичним інструкціям завантажувати свої операнди з пам'яті та / або зберігати їх результати в пам'яті; ARM - це архітектура завантаження, і, отже, є лише кілька спеціальних інструкцій для доступу до пам'яті. Тим часом x86 має спеціальні інструкції з умовними галузями, тоді як ARM дозволяє практично всі інструкції виконувати умовно. Також ARM дозволяє виконувати зсуви бітів як частина більшості арифметичних інструкцій. Ці відмінності призводять до різних характеристик продуктивності, відмінностей у внутрішньому дизайні та вартості мікросхем, та відмінності в техніках програмування на рівні мови складання.

Висновок

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


Відмінна відповідь! Люди недостатньо добре розуміють, що обчислювальні речі, які потрібно запрограмувати, є скрізь серед нас. Це не лише програми, які ми бачимо на своїх екранах. Скільки мільярдів чіпів виробляється щороку?
ph

4

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


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

@slebetman - gcc дозволяє вставити змінну в регістр, не вдаючись до складання.
Jirka Hanika

@JirkaHanika: ви говорите про регістри процесора або апаратні регістри спеціального призначення, адресовані спеціальними інструкціями? Я підозрюю, що слебетман означає останнє.
PJTraill

"Усі коди" - "GCC робить краще" = "ви використовуєте ассемблер". Так, ви можете отримати доступ до регістрів без вставки асемблера.
Злий

@PJTraill - коментар Slebetman, як правило, відмінний і, можливо, його слід включити у відповідь. Але обидва його приклади (реєстраційний доступ та дерево джерела Linux), швидше за все, подаватимуть поширені помилки, а не те, що вони стануть прекрасними прикладами того, що не можна робити в C із розширеннями gcc; їх слід замінити або пропустити. (Якщо сьогодні є вказівка ​​HW робити щось, у вас буде відповідне розширення gcc на рік. Не завжди, але дуже часто. Приклади віку.)
Jirka Hanika

3

Microsoft винайшла MSIL як проміжну мову складання. Програми збиратимуться з C # або VB.Net до MSIL. Під час виконання MSIL був скомпільований для машинного коду для машини, яка запускала його за допомогою компілятора JIT . Файл, що містить MSIL, був файлом .EXE з декількома інструкціями на початку X86 для запуску програми. На процесорі ARM слід ввести слово моно перед іменем програми, щоб запустити його.


Яка різниця між "мовою проміжної збірки" та "віртуальною машиною"?
Боб Джарвіс - Відновіть Моніку

@BobJarvis: Один - код, а інший - перекладач. Ви мали б запитати, яка різниця між проміжною збіркою та байт
кодом

Схоже, це не відповідає на питання. Поки кожна машина компілює / збирає MSIL по-різному, в цьому немає нічого універсального, і метою такої компіляції є перенесення загальної функціональності, а не використання певного набору інструкцій, який, як вказує DW, є (або а) причина використання асемблера.
PJTraill

3

Як зазначалося, LLVM - це найближче до цього часу. Великим бар'єром для справді універсальної мови ставатимуть фундаментальні відмінності, пов'язані з неявними компромісами: паралельність, використання пам'яті, пропускна здатність, затримка та енергоспоживання. Якщо ви пишете в явно SIMD-стилі, ви могли б використовувати занадто багато пам'яті. Якщо ви пишете в явно стилі SISD, ви отримаєте неоптимальну паралелізацію. Якщо ви оптимізуєте пропускну здатність, вам зашкодить затримка. Якщо ви максимізуєте одноточну пропускну здатність (тобто тактову частоту), вам зашкодить термін служби акумулятора.

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

Тоді виникає питання невизначеної поведінки. Значна частина швидкості мов C і мов збираються з невизначеної поведінки. Якщо ви визнаєте невизначену поведінку, яка насправді трапляється, ви в кінцевому підсумку обробляєте їх як особливі випадки (тобто: злом архітектури та контексту).


0

Можливо, те, що ви шукаєте, - це позначення універсальної вертушної машини, де всі погоджуються на символи для команд. ( https://en.wikipedia.org/wiki/Universal_Turing_machine )

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

У статті « Мистецтво комп’ютерного програмування» є приклад того, як це може виглядати.

Але розглянемо питання "чому не є їх комерційно доступною універсальною мовою, яку можна використовувати на всіх комп'ютерах", я б припустив, що найбільш домінуючі впливи є (1) зручністю, не всі мови монтажу є найбільш зручними для використання; (2) економічність, забезпечення, несумісність машин різних марок та постачальників - це бізнес-стратегія, а також результат обмежених ресурсів (часу / грошей) на проектування машин.


Питання полягає в питанні мови складання, яку можна використовувати для програмування будь-якого комп’ютера, а не універсальної мови збирання в розумінні "універсальної машини Тьюрінга".
Девід Річербі

1
Церква-Тюрінг повідомляє нам, що UTC може робити те, що може зробити будь-який програмований комп'ютер. Окрім обмежених проблем із фізичним зберіганням. Мова складання для UTC є цілком здійсненною. Але, як я сказав, культурна та економічна практичність може обмежувати фактичне впровадження та прийняття на ринку.
Кріс

Ви пропускаєте найбільшу проблему - це продуктивність ! Навіщо використовувати мову в 1000 разів повільніше лише для якоїсь високої мети бути апаратно-агностичним? Машина Тьюрінга - жахлива модель практичних обчислень.
Артелій

1
Чи бажають коментатори запропонувати будь-якій інформатиці підтримати свої претензії? Це врешті-решт форум з інформатики.
Кріс

1
Я не експерт з CS. Але я вважаю, що архітектура фон Неймана - це блискучий інженерний твір, який дозволяє досягти балансу між програмованістю та продуктивністю, в той час як мета машини Тюрінга - показати, що навіть сама основна машина може обчислити все, що може скласти більш складна машина. Звичайно, ви можете продовжувати додавати все нові й нові функції до машини Тьюрінга (більше стрічок, арифметики), але тоді ви отримаєте ту саму проблему, яку ви мали, в першу чергу, а саме люди, які не погоджуються щодо набору інструкцій. Крім того, відсутність випадкового доступу створює великі накладні витрати у багатьох алгоритмах.
Артелій

0

припущення: компілювати та оптимізувати мову високого рівня L1 до мови нижчого рівня L0 простіше, ніж компілювати та оптимізувати мову високого рівня L2 (вище L1) до L0; простіше в тому сенсі, що ви нібито можете генерувати більш оптимізований код при компілюванні L1 в L0, ніж L2 в L0.

Я вважаю, що припущення, ймовірно, правильне, тому, ймовірно, більшість компіляторів використовують проміжну мову низького рівня (IR / LLVM).

якщо це правда, ніж використання будь-якої мови низького рівня L0 і писати компілятори для перекладу L0 на інші мови низького рівня. Наприклад, використовуйте набір інструкцій MIPS і компілюйте його до x86, arm, power, ...

-Тауфік


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