Подтвердить что ты не робот

Как код сборки кода кода C (например, оптимизированный strlen)?

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

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

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

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

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

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

Ответ 4

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

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

Ответ 5

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

Ответ 6

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