Многие (большинство?) Компиляторы C поддерживают встроенную сборку , хотя это не является частью стандарта. Тем не менее, нет никакой строгой необходимости в компиляторе для поддержки любой такой вещи.
Во-первых, следует признать, что сборка - это в основном просто машинный (полу) читаемый человеком код, и C в любом случае становится машинным кодом.
«Вызов» функции C просто генерирует набор инструкций, которые подготавливают регистры, стек и / или некоторый другой машинно-зависимый механизм согласно некоторому установленному соглашению о вызовах, а затем переходит к началу вызываемой функции.
Блок кода сборки может соответствовать соответствующему соглашению о вызовах и, таким образом, генерировать двоичный объект машинного кода, который может вызвать другой двоичный объект машинного кода, который изначально был написан на языке Си. Разумеется, возможно и обратное.
Подробная информация о соглашении о вызовах, процессе сборки и процессе компоновки (чтобы связать созданный сборкой объектный файл с созданным на C объектным файлом) может сильно различаться между платформами, компиляторами и компоновщиками. Хороший учебник по сборке для выбранной вами платформы, вероятно, охватит такие детали.
Мне нравится x86-центричное Учебное пособие по сборке ПК , в котором конкретно рассматриваются интерфейс сборки и код C.