Возможен ли универсальный язык ассемблера для всех компьютеров?


23

Я хотел бы задать несколько вопросов о языке ассемблера. Насколько я понимаю, это очень близко к машинному языку, что делает его быстрее и эффективнее.

Поскольку у нас существуют разные компьютерные архитектуры, значит ли это, что мне нужно писать разные коды на ассемблере для разных архитектур? Если так, то почему не Assembly, напишите один раз - запустите везде тип языка? Разве не было бы проще сделать его универсальным, чтобы вы писали его только один раз и могли запускать его практически на любой машине с различными конфигурациями? (Я думаю, что это было бы невозможно, но я хотел бы получить конкретные, подробные ответы)

Некоторые люди могут сказать, что C - это язык, который я ищу. Я раньше не использовал C, но думаю, что это все еще язык высокого уровня, хотя, вероятно, быстрее, чем Java, например. Я могу ошибаться здесь.


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

4
Мы ожидаем, что вы проведете значительный объем исследований / самообучения, прежде чем спросить, и расскажете нам в вопросе, какое исследование вы провели. В этом случае исследование может включать чтение соответствующих статей Википедии (например, на ассемблере и компьютерной архитектуре) и чтение учебника по компьютерной архитектуре. Чтобы сделать этот вопрос лучше: сделайте это исследование, если вы еще этого не сделали, а затем отредактируйте вопрос, чтобы объяснить исследование, которое вы сделали. Часто такого рода исследования помогают вам сформулировать лучший вопрос; и в любом случае это помогает ответчикам избежать повторения того, что вы уже знаете.
DW

15
Начните с понимания того, что / почему нет языка с названием Assembly.
Рафаэль

2
Одна «классическая» проблема с переносимостью языка C - это разные размеры примитивов (например, целочисленные) на разных аппаратных средствах, и есть и другие цитируемые.
ВЗН

3
Это скорее социальная проблема, чем техническая. Вам нужно убедить всех производителей процессоров, чтобы их процессоры принимали один и тот же машинный язык. (На самом деле, x86 почти
наверняка

Ответы:


45

Язык ассемблера - это способ написания инструкций для набора команд компьютера, который немного более понятен программистам.

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

Основная причина использования языка ассемблера состоит в том, что он позволяет очень низкоуровнево контролировать вашу программу и использовать все инструкции процессора: настраивая программу, чтобы использовать преимущества, которые уникальны для конкретного процессора. будет работать, иногда вы можете ускорить программу. Философия «один раз запусти везде» в корне противоречит этому.


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

26
@nTuply Как только вы измените свой язык ассемблера для обслуживания различных машин, он станет языком высокого уровня с ужасным синтаксисом в стиле ассемблера. Как только вы решили использовать язык высокого уровня, вы можете также использовать язык с более дружественным синтаксисом и позволить компилятору выполнять тяжелую работу.
Дэвид Ричерби

15
Это не совсем глупая идея иметь «язык ассемблера», который переводится для разных машин, потому что это в основном то, что «IR» в LLVM. Однако по причинам, которые приводит Дэвид, вы обычно не пишете сборку LLVM. Кроме того, поскольку в 99 случаях из 100 вы выполняете работу хуже, чем clang, переводя C на LLVM. Языки ассемблера потенциально более эффективны, чем языки высокого уровня, но в руках большинства современных программистов, у которых обычно есть время для оптимизации, они в любом случае не достигают своего потенциала.
Стив Джессоп

9
@nuply, это существует. Процесс перехода от этого дополнительного языка ассемблера к машинным инструкциям называется компиляцией.
Пол Дрейпер

3
@PJTraill Нет никакой причины писать компилятор на ассемблере в современной системе, за исключением самого первого шага начальной загрузки (и в большинстве случаев, даже тогда). Компиляторы, написанные на языке высокого уровня, с гораздо большей вероятностью будут реально обслуживаемыми. Также сравните Как язык, чей компилятор написан на C, может быть быстрее C? , Целью компилятора является перевод с одного языка (исходного языка) на другой (обычно машинный язык для конкретной архитектуры и ОС); это может быть написано на любом языке.
CVn

13

ОПРЕДЕЛЕНИЕ языка ассемблера состоит в том, что это язык, который может быть переведен непосредственно в машинный код. Каждый код операции на языке ассемблера преобразуется ровно в одну операцию на целевом компьютере. (Ну, это немного сложнее, чем это: некоторые ассемблеры автоматически определяют «режим адресации» на основе аргументов кода операции. Но, тем не менее, принцип заключается в том, что одна строка сборки переводится в одну инструкцию машинного языка.)

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

Ваш вопрос немного похож на вопрос: «Можно ли сделать лодку, которая не плывет или не имеет другого способа путешествовать по воде, но имеет колеса и мотор и может путешествовать по суше?» Ответ будет таким: по определению, такой автомобиль не будет лодкой. Это больше похоже на машину.


1
C часто называют «переносимым языком ассемблера».
Ларри Гритц

2
@LarryGritz Конечно. И когда был изобретен C, он был новаторским: он предлагал большую часть языка ассемблера с простотой использования скомпилированного. Но по определению это все еще скомпилированный язык
Jay

8

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

Однако на практике существуют разные микросхемы для разных целей с разными принципами работы и проектирования (например, RISC и CISC), которые служат разным целям, и наборы команд, которые ими управляют, и языки ассемблера различаются. В конце концов, ответ такой же, как и на вопрос, почему существует так много разных языков программирования : разные цели, разные дизайнерские решения.

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


6
«если возможно крошечный» - тут есть два типа программистов. Те, кто считает C языком низкого уровня, потому что его основные операции очень похожи на те вещи, которые появляются в наборах команд ЦП, и те, кто считает C языком высокого уровня, потому что это не тот же набор команд, что и машина.
Стив Джессоп

Если под языком ассемблера вы подразумеваете тот, который дает полный контроль над машинным кодом, сгенерированным для определенного типа (или семейства) аппаратных средств, было бы возможно определить один язык «для всех компьютеров» в нашем мире в данный момент, но это должен продолжать меняться. По общему признанию (если бы он хорошо спроектирован) сократил бы кривую обучения кодированию для новой архитектуры, но я ожидаю, что любая работа, которую вы захотите делать с ней, а не компилятор, будет применяться только к крошечной части архитектур. То, что компьютеры одинаковы на абстрактном уровне, это красная селедка, речь идет о машинном коде.
PJTraill

7

Вы упоминаете фразу «напиши когда-нибудь, беги куда-нибудь», не замечая, чтобы заметить ее значение. Это маркетинговый слоган для Sun Microsystems, которая коммерчески изобрела концепцию «виртуальной машины» и «байткодов» для Java, хотя , возможно , идея , возможно, возникла в научных кругах 1 - й, Позднее идея была скопирована Microsoft для .Net после того, как Sun успешно подала в суд на них за нарушение лицензионного соглашения с Java. Java-байт-коды - это реализация идеи межмашинной сборки или машинного языка. Они используются для нескольких других языков, отличных от Java, и теоретически могут использоваться для компиляции любого языка. После многих лет очень продвинутой оптимизации Java приблизилась по производительности к компилируемым языкам, демонстрируя, что цель высокопроизводительной технологии виртуальной машины, не зависящей от платформы, в целом достижима.

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


8
Sun не изобрела ни виртуальные машины, ни байт-код, они даже не были первой группой, заработавшей на них деньги. Посмотрите p-код.
Jmoreno

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

статья не претендует на изобретенные солнцем виртуальные машины / байт-код. есть другая история, на которую не ссылаются, но на которую ссылаются. Кстати, еще одна ключевая технология, очень актуальная здесь: нативный клиент Google (функция Chrome)
vzn

5

Причины высокого уровня

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

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

Итак, у нас есть много разных «ароматов» микропроцессора, каждый из которых имеет свои сильные и слабые стороны. Всем им желательно использовать совместимый набор инструкций, поскольку это позволяет повторно использовать код и облегчает поиск людей с нужными навыками. Тем не менее, набор команд делает влияет на стоимость, сложность, скорость, простоту в использовании, а также физические ограничения процессора, и поэтому у нас есть компромисс: есть несколько «основных» наборы команд (и многие незначительные), и в каждом наборе команд есть много процессоров с различными характеристиками.

Да, и по мере того, как технология меняется, все эти компромиссы меняются, поэтому наборы инструкций развиваются, появляются новые и умирают старые. Даже если бы был «лучший» набор инструкций сегодня, это может быть не через 20 лет.

Детали оборудования

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

Это не просто перевод инструкций из одного набора инструкций в другой. Совершенно другой подход может быть предпочтительным в другом наборе команд. Например, на 8-битном процессоре справочная таблица может быть идеальной, тогда как на 32-битном процессоре арифметическая операция была бы лучше для той же цели.

Есть и другие важные различия между наборами команд. Большинство инструкций делятся на четыре категории:

  • Вычисления (Арифметика и логика)
  • Контроль потока
  • Обмен данными
  • Конфигурация процессора

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

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

x86 позволяет арифметическим инструкциям загружать свои операнды из памяти и / или сохранять свои результаты в памяти; ARM - это архитектура хранилища нагрузки, поэтому в ней есть только несколько специальных инструкций для доступа к памяти. Между тем, x86 имеет специальные инструкции условного перехода, а ARM позволяет выполнять практически все инструкции условно. Кроме того, ARM позволяет выполнять сдвиги битов как часть большинства арифметических инструкций. Эти различия приводят к различным характеристикам производительности, различиям во внутреннем дизайне и стоимости микросхем, а также различиям в методах программирования на уровне ассемблера.

Вывод

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


Отличный ответ! Люди недостаточно хорошо понимают, что компьютерные вещи, которые должны быть запрограммированы, повсюду среди нас. Это не просто приложения, которые мы видим на наших экранах. Сколько миллиардов чипов производится каждый год?
тел.

4

Добавление к изумительному ответу DW: если вы хотите иметь одного ассемблера, ему нужно поддерживать все архитектуры, безупречный переводчик среди них и полностью понимать, что вы делаете.
Некоторые сильно оптимизированные коды для одной архитектуры должны быть деоптимизированы, поняты на более абстрактном уровне и оптимизированы для другой.
Но если бы это было возможно, у нас был бы идеальный компилятор C, и запись в чистом виде не принесла бы никакой пользы.
Основной смысл использования ассемблера - это производительность, которую нельзя выжать из последних компиляторов.
Написание такой программы будет еще сложнее, чем у существующих компиляторов, а поддержка всех создаваемых новых архитектур сделает ее еще сложнее.
А для программы «один-единственный» это также будет означать полную обратную совместимость.


В подавляющем большинстве случаев gcc выполняет лучшую оптимизацию, чем программист. Основной смысл использования ассемблера состоит в том, чтобы делать вещи, которые вы не можете сделать в C, такие как доступ к регистрам. Если вы посмотрите на дерево исходных текстов Linux, это то, для чего они используют сборку.
Slebetman

@slebetman - gcc позволяет поместить переменную в регистр, не прибегая к сборке.
Джирка Ханика

@JirkaHanika: вы говорите о регистрах ЦП или аппаратных регистрах специального назначения, адресованных специальными инструкциями? Я подозреваю, что slebetman означает последнее.
PJTraill

«Все коды» - «GCC лучше» = «Вы используете ассемблер». Да, вы можете получить доступ к регистрам без вставок ассемблера.
Зло

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

3

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


В чем разница между "языком промежуточной ассемблера" и "виртуальной машиной"?
Боб Джарвис - Восстановить Монику

@BobJarvis: один код, а другой переводчик. Вы должны были спросить, в чем разница между промежуточной сборкой и байт-кодом
slebetman

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

3

Как уже отмечалось, LLVM является наиболее близким к этому моменту. Большим барьером для действительно универсального языка будут фундаментальные различия, связанные с неявными компромиссами: параллелизм, использование памяти, пропускная способность, задержка и энергопотребление. Если вы пишете в явно SIMD-стиле, вы можете использовать слишком много памяти. Если вы пишете в явном стиле SISD, вы получите субоптимальное распараллеливание. Если вы оптимизируете пропускную способность, вы повредите задержку. Если вы максимизируете однопоточную пропускную способность (т. Е. Тактовую частоту), это ухудшит срок службы батареи.

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

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


0

Возможно, вы ищете нотацию универсальной токарной машины, в которой все согласны с символами команд. ( https://en.wikipedia.org/wiki/Universal_Turing_machine )

«Ассемблер», который переводит язык Turning Acceptable в машинный код соответствующего поставщика и предназначен для любой из тех вещей, которые мы называем компьютерами.

В « Искусстве компьютерного программирования» есть пример того, как это может выглядеть.

Но рассмотрим вопрос «почему это не коммерчески доступный универсальный язык, который можно использовать со всеми компьютерами»? Я бы предположил, что наиболее доминирующим влиянием является (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, ...

-Taoufik


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