Вы, кажется, немного смущены тем, как работает процессор. Сборка не является отдельным языком от машинного кода. Это просто другое (текстовое) представление.
Код сборки - это просто последовательный список инструкций, которые должны быть выполнены. И машинный код это точно то же самое. Каждая команда, поддерживаемая ЦП, имеет определенный битовый шаблон, который вызывает ее выполнение, а также текстовое имя, которое вы можете использовать в коде сборки.
Если я пишу add $10, $9, $8
и запускаю его через ассемблер, я получаю машинный код для инструкции добавления, получая значения в регистрах 9 и 8, добавляя их и сохраняя результат в регистре 10.
Между ассемблером и машинным кодом существует соотношение 1: 1.
Также нет "вызовов API". Процессор просто читает с адреса X и сопоставляет последующие биты со всеми инструкциями, которые он понимает. Как только он находит инструкцию, которая соответствует этому битовому шаблону, он выполняет инструкцию и переходит к чтению следующей.
То, что вы спрашиваете, в некотором смысле невозможно или противоречие. IL означает Intermediate Language, то есть своего рода псевдокод, который генерируется компилятором, но еще не переведен в машинный код. Но если процессор может выполнить это напрямую, он больше не будет промежуточным, он будет машинным кодом.
Таким образом, возникает вопрос: «Является ли ваш IL-код лучшим, более эффективным представлением программы, чем машинный код, который сейчас поддерживает ЦП?»
И ответ, скорее всего, нет. MSIL (я полагаю, это то, что вы имеете в виду под ИЛ, что является гораздо более общим термином) разработан так, чтобы быть переносимым, простым и последовательным. Каждый язык .NET компилируется в MSIL, и каждая программа MSIL должна быть в состоянии перевести в машинный код для любого процессора в любом месте. Это означает, что MSIL должен быть общим и абстрактным, а не делать предположения о процессоре. По этой причине, насколько мне известно, это чисто стековая архитектура. Вместо хранения данных в регистрах каждая инструкция обрабатывает данные в верхней части стека. Это хорошая, чистая и универсальная система, но она не очень эффективна и плохо отражается на жесткой структуре процессора. (В вашем замечательном маленьком мире высокого уровня вы можете притворяться, что стек может свободно расти. Чтобы центральный процессор мог получить к нему быстрый доступ, он должен храниться в некоторой небольшой быстрой встроенной памяти с конечным размером. Итак, что происходит если ваша программа помещает слишком много данных в стек?)
Да, вы могли бы сделать ЦП для непосредственного выполнения MSIL, но что бы вы получили?
Вам больше не нужно JIT-код перед выполнением, поэтому при первом запуске программы она запускается немного быстрее. Кроме этого, хотя? После того как ваша MSIL-программа была обработана JIT, она была переведена в машинный код и работает так же эффективно, как если бы она была изначально написана в машинном коде. Байт-код MSIL больше не существует, это просто последовательность инструкций, понятная ЦП.
На самом деле, вы вернетесь туда, где были до .NET. Неуправляемые языки компилируются прямо в машинный код, как это было бы в вашем предложении. Единственное отличие состоит в том, что неуправляемый код предназначен для машинного кода, который разработан проектировщиками ЦП так, чтобы он подходил для выполнения на ЦП, в то время как в вашем случае он предназначен для машинного кода, который разработан проектировщиками программного обеспечения, чтобы его было легко переводить с.