Я хотел бы задать несколько вопросов о языке ассемблера. Насколько я понимаю, это очень близко к машинному языку, что делает его быстрее и эффективнее.
Поскольку у нас существуют разные компьютерные архитектуры, значит ли это, что мне нужно писать разные коды на ассемблере для разных архитектур? Если так, то почему не Assembly, напишите один раз - запустите везде тип языка? Разве не было бы проще сделать его универсальным, чтобы вы писали его только один раз и могли запускать его практически на любой машине с различными конфигурациями? (Я думаю, что это было бы невозможно, но я хотел бы получить конкретные, подробные ответы)
Некоторые люди могут сказать, что C - это язык, который я ищу. Я раньше не использовал C, но думаю, что это все еще язык высокого уровня, хотя, вероятно, быстрее, чем Java, например. Я могу ошибаться здесь.
Ответы:
Язык ассемблера - это способ написания инструкций для набора команд компьютера, который немного более понятен программистам.
Разные архитектуры имеют разные наборы инструкций: набор разрешенных инструкций различен для каждой архитектуры. Таким образом, вы не можете надеяться на то, что у вас будет ассемблерная программа с однократной записью и везде. Например, набор инструкций, поддерживаемых процессорами x86, сильно отличается от набора инструкций, поддерживаемых процессорами ARM. Если бы вы написали программу сборки для процессора x86, в ней было бы много инструкций, которые не поддерживаются процессором ARM, и наоборот.
Основная причина использования языка ассемблера состоит в том, что он позволяет очень низкоуровнево контролировать вашу программу и использовать все инструкции процессора: настраивая программу, чтобы использовать преимущества, которые уникальны для конкретного процессора. будет работать, иногда вы можете ускорить программу. Философия «один раз запусти везде» в корне противоречит этому.
источник
ОПРЕДЕЛЕНИЕ языка ассемблера состоит в том, что это язык, который может быть переведен непосредственно в машинный код. Каждый код операции на языке ассемблера преобразуется ровно в одну операцию на целевом компьютере. (Ну, это немного сложнее, чем это: некоторые ассемблеры автоматически определяют «режим адресации» на основе аргументов кода операции. Но, тем не менее, принцип заключается в том, что одна строка сборки переводится в одну инструкцию машинного языка.)
Вы можете, без сомнения, изобрести язык, который будет похож на ассемблер, но будет переведен на разные машинные коды на разных компьютерах. Но по определению это не будет ассемблер. Это был бы язык более высокого уровня, похожий на язык ассемблера.
Ваш вопрос немного похож на вопрос: «Можно ли сделать лодку, которая не плывет или не имеет другого способа путешествовать по воде, но имеет колеса и мотор и может путешествовать по суше?» Ответ будет таким: по определению, такой автомобиль не будет лодкой. Это больше похоже на машину.
источник
Нет никакой концептуальной (я полагаю, нет информатики ) причины , по которой нельзя было бы использовать один язык ассемблера для всех компьютеров в мире. На самом деле, это сделало бы многое проще. Что касается теории, они все равно, в любом случае, до какой-то забавной биекции.
Однако на практике существуют разные микросхемы для разных целей с разными принципами работы и проектирования (например, RISC и CISC), которые служат разным целям, и наборы команд, которые ими управляют, и языки ассемблера различаются. В конце концов, ответ такой же, как и на вопрос, почему существует так много разных языков программирования : разные цели, разные дизайнерские решения.
Тем не менее, вы можете, конечно, ввести уровни абстракции, чтобы добраться до некоторого общего интерфейса. Например, x86 уже давно ликвидирован на уровне чипов; есть небольшое аппаратное обеспечение, которое переводит инструкции x86 в то, с чем действительно работает ваш процессор . Такие языки, как C, были бы еще одним шагом от аппаратного обеспечения (если, возможно, крошечного), вплоть до таких языков, как Haskell, Java или Ruby. Да, компилятор является одним из главных достижений информатики, поскольку он позволяет разделить задачи таким образом.
источник
Вы упоминаете фразу «напиши когда-нибудь, беги куда-нибудь», не замечая, чтобы заметить ее значение. Это маркетинговый слоган для Sun Microsystems, которая коммерчески изобрела концепцию «виртуальной машины» и «байткодов» для Java, хотя , возможно , идея , возможно, возникла в научных кругах 1 - й, Позднее идея была скопирована Microsoft для .Net после того, как Sun успешно подала в суд на них за нарушение лицензионного соглашения с Java. Java-байт-коды - это реализация идеи межмашинной сборки или машинного языка. Они используются для нескольких других языков, отличных от Java, и теоретически могут использоваться для компиляции любого языка. После многих лет очень продвинутой оптимизации Java приблизилась по производительности к компилируемым языкам, демонстрируя, что цель высокопроизводительной технологии виртуальной машины, не зависящей от платформы, в целом достижима.
Еще одна новая идея на ранних стадиях / в обращении, связанная с вашими требованиями, называется проектом пересчета и предназначена для научных исследований, хотя может использоваться и для других целей. Идея состоит в том, чтобы сделать вычислительные эксперименты воспроизводимыми с помощью технологии виртуальных машин. Это в основном идея моделирования различных машинных архитектур на произвольном оборудовании.
источник
Причины высокого уровня
Когда вы думаете об этом, микропроцессор делает удивительную вещь: он позволяет вам взять машину (например, стиральную машину или лифт) и заменить целый кусок специально разработанных механизмов или цепей на дешевый, производимый массово кремний чип. Вы экономите много денег на деталях и много времени на дизайне.
Но подождите, стандартный чип, заменяющий бесчисленное множество нестандартных конструкций? Не может быть одного идеального микропроцессора, который идеально подходил бы для любого применения. Некоторые приложения должны минимизировать энергопотребление, но не должны быть быстрыми; другие должны быть быстрыми, но не должны легко программироваться, другие должны быть дешевыми и т. д.
Итак, у нас есть много разных «ароматов» микропроцессора, каждый из которых имеет свои сильные и слабые стороны. Всем им желательно использовать совместимый набор инструкций, поскольку это позволяет повторно использовать код и облегчает поиск людей с нужными навыками. Тем не менее, набор команд делает влияет на стоимость, сложность, скорость, простоту в использовании, а также физические ограничения процессора, и поэтому у нас есть компромисс: есть несколько «основных» наборы команд (и многие незначительные), и в каждом наборе команд есть много процессоров с различными характеристиками.
Да, и по мере того, как технология меняется, все эти компромиссы меняются, поэтому наборы инструкций развиваются, появляются новые и умирают старые. Даже если бы был «лучший» набор инструкций сегодня, это может быть не через 20 лет.
Детали оборудования
Вероятно, самое большое дизайнерское решение в наборе команд - это размер слова , т. Е. Насколько велико число, которым процессор может «естественным образом» манипулировать. 8-разрядные процессоры работают с числами от 0 до 255, тогда как 32-разрядные процессоры работают с числами от 0 до 4 294 967 295. Код, разработанный для одного, должен быть полностью переосмыслен для другого.
Это не просто перевод инструкций из одного набора инструкций в другой. Совершенно другой подход может быть предпочтительным в другом наборе команд. Например, на 8-битном процессоре справочная таблица может быть идеальной, тогда как на 32-битном процессоре арифметическая операция была бы лучше для той же цели.
Есть и другие важные различия между наборами команд. Большинство инструкций делятся на четыре категории:
Процессоры различаются по типу вычислений, которые они могут выполнять, а также по тому, как они приближаются к потоку управления, передаче данных и конфигурации процессора.
Например, некоторые процессоры AVR не могут ни умножать, ни делить; тогда как все процессоры x86 могут. Как вы можете себе представить, устранение схем, необходимых для таких задач, как умножение и деление, может сделать процессор проще и дешевле; эти операции все еще могут быть выполнены с использованием программных подпрограмм, если они необходимы.
x86 позволяет арифметическим инструкциям загружать свои операнды из памяти и / или сохранять свои результаты в памяти; ARM - это архитектура хранилища нагрузки, поэтому в ней есть только несколько специальных инструкций для доступа к памяти. Между тем, x86 имеет специальные инструкции условного перехода, а ARM позволяет выполнять практически все инструкции условно. Кроме того, ARM позволяет выполнять сдвиги битов как часть большинства арифметических инструкций. Эти различия приводят к различным характеристикам производительности, различиям во внутреннем дизайне и стоимости микросхем, а также различиям в методах программирования на уровне ассемблера.
Вывод
Причина, по которой невозможно создать универсальный язык ассемблера, заключается в том, что для правильного преобразования ассемблерного кода из одного набора команд в другой необходимо заново разрабатывать код - что-то, чего еще не могут сделать компьютеры.
источник
Добавление к изумительному ответу DW: если вы хотите иметь одного ассемблера, ему нужно поддерживать все архитектуры, безупречный переводчик среди них и полностью понимать, что вы делаете.
Некоторые сильно оптимизированные коды для одной архитектуры должны быть деоптимизированы, поняты на более абстрактном уровне и оптимизированы для другой.
Но если бы это было возможно, у нас был бы идеальный компилятор C, и запись в чистом виде не принесла бы никакой пользы.
Основной смысл использования ассемблера - это производительность, которую нельзя выжать из последних компиляторов.
Написание такой программы будет еще сложнее, чем у существующих компиляторов, а поддержка всех создаваемых новых архитектур сделает ее еще сложнее.
А для программы «один-единственный» это также будет означать полную обратную совместимость.
источник
Microsoft изобрела MSIL как язык промежуточной ассемблера. Программы будут компилироваться из C # или VB.Net в MSIL. Во время выполнения MSIL был скомпилирован в машинный код для машины, на которой он работал, с использованием JIT- компилятора. Файл, содержащий MSIL, был .EXE-файлом с несколькими инструкциями в начале в X86 для запуска программы. На процессоре ARM вы должны ввести слово mono перед именем программы, чтобы запустить его.
источник
Как уже отмечалось, LLVM является наиболее близким к этому моменту. Большим барьером для действительно универсального языка будут фундаментальные различия, связанные с неявными компромиссами: параллелизм, использование памяти, пропускная способность, задержка и энергопотребление. Если вы пишете в явно SIMD-стиле, вы можете использовать слишком много памяти. Если вы пишете в явном стиле SISD, вы получите субоптимальное распараллеливание. Если вы оптимизируете пропускную способность, вы повредите задержку. Если вы максимизируете однопоточную пропускную способность (т. Е. Тактовую частоту), это ухудшит срок службы батареи.
По крайней мере, код должен быть аннотирован компромиссами. Что может быть наиболее важным, так это чтобы язык имел хорошие алгебраические свойства / свойства типов, которые дают компилятору много возможностей для оптимизации и обнаружения логической несогласованности.
Тогда возникает вопрос неопределенного поведения. Большая часть скорости C и ассемблера происходит от неопределенного поведения. Если вы допускаете неопределенное поведение, которое на самом деле происходит, то в конечном итоге вы обрабатываете их как особые случаи (например, специфические для архитектуры и контекста хаки).
источник
Возможно, вы ищете нотацию универсальной токарной машины, в которой все согласны с символами команд. ( https://en.wikipedia.org/wiki/Universal_Turing_machine )
«Ассемблер», который переводит язык Turning Acceptable в машинный код соответствующего поставщика и предназначен для любой из тех вещей, которые мы называем компьютерами.
В « Искусстве компьютерного программирования» есть пример того, как это может выглядеть.
Но рассмотрим вопрос «почему это не коммерчески доступный универсальный язык, который можно использовать со всеми компьютерами»? Я бы предположил, что наиболее доминирующим влиянием является (1) удобство, не все языки ассемблера являются наиболее удобными для использования; (2) экономика, обеспечение, несовместимость между машинами разных брендов и поставщиков является бизнес-стратегией, а также результатом ограниченных ресурсов (время / деньги) для проектирования машин.
источник
допущение: компиляция и оптимизация языка высокого уровня L1 для языка нижнего уровня L0 проще, чем компиляция и оптимизация языка высокого уровня L2 (выше, чем L1) для L0; проще в том смысле, что вы, вероятно, можете генерировать более оптимизированный код при компиляции L1 в L0, чем в L2 в L0.
Я думаю, что предположение, вероятно, является правильным, поэтому, вероятно, большинство компиляторов используют промежуточный язык низкого уровня (IR / LLVM).
если это так, тогда используйте любой язык низкого уровня L0 и напишите компиляторы для перевода L0 в другие языки низкого уровня. Например, используйте набор инструкций MIPS и скомпилируйте его в x86, arm, power, ...
-Taoufik
источник