Что означает __asm ​​("LOS_##_ns")

Я пытаюсь получить некоторое представление о том, как работает реализация указателя Apple OS. Я работаю с C API (есть и Swift API). Моя конечная цель — попытаться создать для них класс-оболочку C++ в стиле RAII, что сложнее, чем может показаться.

Расширение макроса os_signpost_emit_with_type показывает, что он создает статические строки из строковых литералов, переданных этому макросу, которые выглядят следующим образом:

__attribute__((section("__TEXT,__oslogstring,cstring_literals"), internal_linkage)) static const char string_name[] __asm (OS_STRINGIFY(OS_CONCAT(LOS_##_ns, __COUNTER__))) = "string literal";

Эти строки позже появятся в качестве имен указателей в профилировщике инструментов. Читая этот код, я понял, что строка помещается в определенный раздел двоичного файла, чтобы профилировщик мог ее найти. Что меня смущает, так это утверждение __asm перед заданием. Очевидно, что с помощью макроса __COUNTER__ он расширяется до чего-то вроде __asm ("LOS_##_ns0"), __asm ("LOS_##_ns1") с уникальным числом для каждой строки. У меня очень мало глубоких знаний, когда дело доходит до сборки, я пытался немного изучить значение этого утверждения, но не получил никаких полезных результатов.

Мое тестирование методом проб и ошибок показало, что уникальность этого числового приложения, сгенерированного макросом __COUNTER__, имеет значение, если встречаются два повторяющихся значения, строка с этим повторяющимся значением будет затенять другую в выходных данных профилировщика.

Может ли кто-нибудь со сборкой знать, как объяснить, что здесь происходит, разработчику C++, как я?

Бонусный вопрос: есть ли способ сгенерировать эту инструкцию из кода C++, где уникальное числовое значение, сгенерированное __COUNTER__, будет взято из какой-то переменной?

stackoverflow.com/questions/2025858/… отвечает на ваш вопрос?

KamilCuk 16.02.2023 10:16

Нет, совсем нет. Символы ## в приведенной выше строке инструкции встроенного ассемблера не являются конкатенацией строк препроцессора, а фактически являются частью строкового литерала, переданного в __asm()

PluginPenguin 16.02.2023 10:17

Это вопрос C или C++? Он помечен как C, но описание продолжает ссылаться на C++.

Tom Karzes 16.02.2023 11:37

Код, о котором идет речь, определенно является кодом C. В конце концов я хочу создать оболочку C++ вокруг него, но для этого мне сначала нужно понять значение этой чистой конструкции C/inline Assembly, поэтому я бы рассматривал это как вопрос C.

PluginPenguin 16.02.2023 11:52
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Общее примечание: для получения информации о расширениях clang вам, как правило, следует обращаться к документации gcc. clang стремится быть совместимым с gcc, поэтому они не удосужились написать независимые документы.

Итак, в вашем примере используется несколько разных расширений. Обратите внимание, что ни один из них не является частью стандарта C или C++.

  1. __attribute__((section ("foo")) помещает переменную в раздел с именем foo, заставляя компилятор выдать директиву .section в сборку перед размещением метки для переменной. См. https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Common-Variable-Attributes.html#Common-Variable-Attributes. Похоже, вы уже знаете об этом.

  2. asm в объявлении не является встроенной сборкой как таковой; он просто сообщает компилятору, какое имя символа использовать для этой переменной, когда он генерирует ассемблерный код. __asm — это просто вариант написания asm. См. https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Asm-Labels.html#Asm-Labels. Итак, int foo asm("bar") = 7; определяет переменную, которая будет называться foo в исходном коде C, но чья метка в ассемблере будет называться bar.

  3. __COUNTER__ — это специальный макрос, определяемый препроцессором gcc/clang, который просто увеличивается при каждом раскрытии. См. https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html#Common-Predefined-Macros

Спасибо, хотя я знал о 1. и 3., значение __asm в этом контексте было мне непонятно. Таким образом, кажется, что по некоторым причинам имена переменных сборки для этих строк указателей должны следовать определенному шаблону. Есть ли шанс, что строка, переданная ключевому слову asm, получена из параметра шаблона окружающего класса или это должен быть жестко заданный строковый литерал?

PluginPenguin 16.02.2023 16:07

Примечание. Для этого я создал отдельный дополнительный вопрос stackoverflow.com/questions/75475256/…

PluginPenguin 16.02.2023 17:31

@PluginPenguin: вам придется попробовать, но я думаю, что нет, это должен быть настоящий литерал (конечно, после расширения препроцессора). В документах просто сказано «строковая константа» без уточнения.

Nate Eldredge 17.02.2023 00:48

Другие вопросы по теме