Ассемблер не бестиповый: как устроен инлайн-ассемблер Odin

Everyone says assembly is untyped—everyone is wrong

Автор Odin утверждает, что его инлайн-ассемблер — лучший среди всех языков. В отличие от GCC, Clang и Rust, где ассемблерные вставки — это строки с минимумом проверок, Odin использует шаблоны `asm`, которые полностью типизированы и интегрированы с языком. Синтаксис единый для всех ISA, а регистры и операнды проверяются компилятором. Система была создана примерно за семь дней.

Ассемблер — это фактически полиадическая типизированная алгебра, которую все договорились считать супом из байтов.
  1. amluto

    У меня очень неоднозначное мнение насчёт этого пользовательского синтаксиса. По моему мнению, правильный синтаксис ассемблера, за очень редкими исключениями, — это тот, что в руководстве. Именно поэтому синтаксис Intel правильный, а AT&T — нет: ISA происходит от Intel, документация от Intel и AMD, и в этих документах используется синтаксис Intel.

    Поэтому я в некотором роде надеялся, что пользовательский синтаксис по крайней мере приведёт к очень, очень строгой проверке, по крайней мере не хуже, чем у Fil-C. Возможно, с запасным выходом, чтобы сказать что-то вроде: «Я знаю, что выглядит так, будто я испортил xyz, но я обещаю, что на самом деле не испортил».

    К сожалению, пример с CPUID в статье, судя по всему, компилируется, но, по моему мнению, не должен был: CPUID принимает два входа, в EAX и ECX, а в примере забыли привязать ECX как вход. Можно утверждать, что CPUID принимает даже больше входов, если вы на виртуальной машине и делаете что-то особенное, но ECX действительно совершенно однозначен.

  2. jcranmer

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

    Если посмотреть на то, как, скажем, ядро Linux использует инлайн-ассемблер, то на самом деле оно просто хочет, чтобы инлайн-ассемблер передавался напрямую ассемблеру. В инлайн-ASM много директив ассемблера, чтобы делать такие вещи, как определение инструкций, которые ассемблер ещё не знает, или делать причудливые вещи, например, строить систему исправления инструкций во время выполнения. У меня в одном из проектов есть инлайн-ASM, который переключается между 16-битными, 32-битными и 64-битными инструкциями.

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

  3. WalterBright

    Вот как это делает D для x86_64:

    https://github.com/dlang/dmd/blob/master/druntime/src/core/i...

    Это форма оператора, использует синтаксис Intel, и компилятор отслеживает, какие регистры изменяются.

  4. AshamedCaptain

    > AT&T запекает ширину в мнемонику (movb, movw, movl, movq [...] В синтаксисе Intel префикс памяти указывается как byte, word, dword или qword, но Odin просто использует систему типов Odin напрямую.

    В GAS вы можете пропустить суффикс ширины в мнемонике, и в большинстве ассемблеров Intel вы можете пропустить операторы типа памяти, такие как byte. Они с радостью угадывают это по операндам. Проблема в том, что на x86 (но также и на других ISA, даже если в меньшей степени) разные размеры операндов имеют много побочных эффектов, поэтому все просто делают размер операнда явным, до такой степени, что, по-видимому, автор/LLM считает, что указывать их обязательно.

    Это в некоторой степени опровергает заголовок статьи...

    Завтра вам нужно передать 128-битное целое в два регистра, и ваш причудливый синтаксис тогда тоже превращается в беспорядочный набор хаков. Вот почему у всех синтаксис инлайн-ассемблера выглядит именно так, потому что они хотят охватить странные случаи (у gcc он почти как историческая книга). Обычно вы используете инлайн-ассемблер, когда у вас есть какой-то нелепый крайний случай, если нет, то вам следует использовать что-то более похожее на встроенные функции...

    Также он забывает про Watcom C, у которого действительно есть полный, но запутанный синтаксис для инлайн-ассемблера (который хорошо сочетается с его способностью задавать действительно странные соглашения о вызовах).

  5. sxzygz

    Эта статья на самом деле о синтаксисе инлайн-ассемблера, разработанном для языка программирования автора Odin (и определённо не о TAL, типизированных языках ассемблера). Здесь много интересных идей.

    Одна из моих критических замечаний, однако, просто указывает на то, насколько похожими стали основные архитектуры процессоров общего назначения; все они — C-машины. Это радикально упрощает сложность на стороне компилятора, где, как кажется, автор нацелен на amd64 и aarch64. Расширение компилятора на rv64, вероятно, будет простым.

    Я ничего не знаю об Odin или его реализации компилятора, но я представляю, что язык придерживается взгляда на машину, который соответствует модели C-машины. Представьте более экзотический язык — компилятору, вероятно, понадобился бы промежуточный язык, соответствующий модели C-машины, и в котором инлайн-ассемблер должен был бы пережить какое-то идемпотентное понижение до промежуточного представления, прежде чем быть далее пониженным до объектного кода. Эти детали — то, что мне действительно любопытно, и, вероятно, наиболее интеллектуально стимулирующее.

    Самая интересная возможность — если компилятор Odin сам полностью написан на Odin. Если бы это было так, это действительно показало бы мощь синтаксиса инлайн-ассемблера. Насколько я знаю, ни один оптимизирующий компилятор действительно не продвигал этот угол, нацеливаясь на несколько архитектур инструкций. Если я правильно помню, даже компилятор Plan9 C перенёс некоторые базовые оптимизации в свою обобщённую часть […]

Ещё за этот день

2026-08-22