Машинно независимый ассемблер или спрятанная виртуальная машина

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

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

Можно создать программу, которая создаёт лёгкий промежуточный код, интерпретируемым другой программой, и запускать, как python, например, через cmd (что-то типа виртуальной машины). И тут другой вопрос: как создать спрятанную виртуальную машину? С помощью популярных некомпилируемых языков исполняемые файлы создаются. Каким образом? Первое, что приходит в голову, — создать bat'ник, в котором прописать:

  1. Поиск на устройстве программы-интерпретатора и вызов ошибки по ненахождении;
  2. Выполнение интерпретатором кода, который тоже лежит в bat-файле.

А для преобразования .bat -> .exe, думаю, сделаны десятки утилит. Так можно создать "псевдоисполняемый" файл, по сути своей являющийся ссылкой на другой файл с параметрами. Я не думаю, что такая реализация критично замедлит выполнение программы, но есть ли способы лучше?


Ответы (2 шт):

Автор решения: Илья К

Прочитай про Байт-код, возможно это то что ты ищешь, либо нет но тогда ты будешь знать что это не то что ты ищешь.

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

→ Ссылка
Автор решения: Alexander Petrov

У каждого процессора своя система команд, соответственно, свой ассемблер. Кроме того, есть ещё и разные виды синтаксисов ассемблера.


Если вас устраивает виртуальная машина, то можно использовать JVM (Java) или CLR (.NET). Есть и другие, но эти самые распространённые и им гарантирована ещё долгая поддержка. Вам достаточно будет перевести код своего языка программирования на байт-код такой машины. Остальное рантайм берёт на себя.
Достоинство этого подхода в том, что упрощается поставка программ для разных платформ: достаточно единственного исполняемого файла.
Недостаток: рантайм должен быть установлен на той машине, где планируется запускать программу.

Однако, ассемблер, это язык низкого уровня. И, раз вы завели речь о нём, то, вероятно, вам нужен более прямой доступ к железу. Тогда стоит посмотреть на LLVM. В этом случае вы аналогично код своего языка программирования будете переводить в промежуточный байт-код LLVM, но после компиляции будете получать готовые программы под конкретную архитектуру процессора.
Достоинство: на конечной машине не нужна исполняющая среда (наподобие JVM или CLR).
Недостаток: нужно компилировать код под каждую платформу отдельно.

My First Language Frontend with LLVM Tutorial.


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

→ Ссылка