Как C-код вызывает ассемблерный код (например, оптимизированный strlen)? - PullRequest
31 голосов
/ 04 сентября 2011

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

Итак, я скажу об этом ясно: как получается, что когда вы вызываете некоторые функции, такие как strlen в системах UNIX / C, настоящая функция, которую вы вызываетенаписано в сборке?Можете ли вы как-нибудь написать ассемблер прямо в программах на C или это внешняя ситуация вызова?Это часть стандарта C, чтобы это можно было сделать, или это специфическая операционная система?

Ответы [ 6 ]

34 голосов
/ 04 сентября 2011

Стандарт C определяет, что должна делать каждая библиотечная функция, а не как она реализована.

Почти все известные реализации C компилируются в машинный язык. Это зависит от разработчиков компилятора / библиотеки C, как они решают реализовать такие функции, как strlen. Они могут решить реализовать его в C и скомпилировать его в объект, или они могут написать его в сборке и собрать его в объект. Или они могли бы реализовать это другим способом. Это не имеет значения, пока вы получаете правильный эффект и результат, когда вы звоните strlen.

Теперь, как это происходит, многие наборы инструментов C позволяют писать встроенную сборку, но это абсолютно не является частью стандарта. Любые такие средства должны быть включены в качестве дополнения к стандарту С.

17 голосов
/ 04 сентября 2011

В конце пути все скомпилированные программы и программы на ассемблере являются машинными языками, поэтому они могут вызывать друг друга. Это достигается путем использования кода сборки, использующего те же соглашения о вызовах (способ подготовки к вызову, параметры и т. Д.), Что и программа, написанная на C. Обзор популярных соглашений о вызовах для процессоров x86 можно найти здесь .

8 голосов
/ 04 сентября 2011

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

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

«Вызов» функции C просто генерирует набор инструкций, которые подготавливают регистры, стек и / или некоторый другой машинно-зависимый механизм согласно некоторому установленному соглашению о вызовах, а затем переходит к началу вызываемой функции.

Блок кода сборки может соответствовать соответствующему соглашению о вызовах и, таким образом, генерировать двоичный объект машинного кода, который может вызвать другой двоичный объект машинного кода, который изначально был написан на языке Си. Разумеется, возможно и обратное.

Подробная информация о соглашении о вызовах, процессе сборки и процессе компоновки (чтобы связать созданный сборкой объектный файл с созданным на C объектным файлом) может сильно различаться между платформами, компиляторами и компоновщиками. Хороший учебник по сборке для выбранной вами платформы, вероятно, охватит такие детали.

Мне нравится x86-центричное Учебное пособие по сборке ПК , в котором конкретно рассматриваются интерфейс сборки и код C.

4 голосов
/ 04 сентября 2011

Когда код C компилируется gcc, он сначала компилируется в инструкции ассемблера, которые затем снова компилируются в двоичный машинно-исполняемый файл.Вы можете увидеть сгенерированные инструкции на ассемблере, указав -S, как в gcc file.c -S.

Код ассемблера просто проходит первый этап компиляции C-to-ассемблера и затем не отличается от кода, скомпилированного из C.

1 голос
/ 04 сентября 2011

Один из способов сделать это - использовать встроенный ассемблер. Это означает, что вы можете написать ассемблерный код прямо в ваш C-код. Конкретный синтаксис зависит от компилятора. Например, см. Синтаксис GCC и Синтаксис MS Visual C ++ .

0 голосов
/ 04 сентября 2011

Вы можете написать встроенную сборку в вашем C-коде.Синтаксис для этого сильно зависит от компилятора, но обычно используется ключевое слово asm.Для получения дополнительной информации см. Встроенную сборку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...