Пояснение % %
Link to originalВвиду того, что сборщик интерпретирует два подряд идущих знака процента как начало комментария, он не отображает содержимое, находящееся между парой таких знаков. Поэтому, чтобы избежать этого, вместо использования %% везде применяется % %.
В GCC встроенный ассемблер использует спецификаторы операндов для указания типа данных, которые будут использоваться в инструкциях. Эти спецификаторы помогают компилятору понять, как обращаться с операндами в ассемблерных вставках. Рассмотрим основные спецификаторы операндов и их использование.
1. “m”
- Описание: Указывает, что операнд находится в памяти.
- Пример:
[array_ptr] "m"(array_ptr)
Пример использования:
int array[5] = {1, 2, 3, 4, 5};
__asm__(
"mov (%[arr]), eax;"
:
: [val] "r"(n)
: "eax"
);
Здесь %[val]
указывает на переменную n
, которая загружается в регистр eax.
3. “i”
- Описание: Указывает, что операнд является немедленным значением (константой).
- Пример:
$1
в командеmov $1, %ecx
Пример использования:
__asm__(
"mov $1, eax;"
:
: [val] "g"(value)
: "eax"
);
Здесь %[val]
указывает на переменную value
, которая может быть размещена в регистре или памяти, в зависимости от оптимизации компилятора.
5. “a”
Пример использования:
int value = 5;
__asm__(
"mov %[val], ebx;"
:
: [val] "b"(value)
: "ebx"
);
Здесь %[val]
указывает на переменную value
, которая загружается в регистр ebx.
7. “c”
Пример использования:
int value = 25;
__asm__(
"mov %[val], edx;"
:
: [val] "d"(value)
: "edx"
);
Здесь %[val]
указывает на переменную value
, которая загружается в регистр edx.
9. “S”
Пример использования:
int source = 45;
__asm__(
"mov %[src], edi;"
:
: [dst] "D"(destination)
: "edi"
);
Здесь %[dst]
указывает на переменную destination
, которая загружается в регистр edi.
Комбинирование спецификаторов
Встроенный ассемблер позволяет комбинировать разные спецификаторы для более гибкого управления операндами.
Пример: Комбинирование спецификаторов
int a = 5, b = 10, result;
__asm__(
"mov %[input_a], eax;"
"mov %%eax, %[output];"
: [output] "=m"(result)
: [input_a] "r"(a), [input_b] "r"(b)
: "eax"
);
Здесь:
"=m"
указывает, что операнд будет записан в память (result
) (Что означает =?)."r"
указывает, что входные операнды будут загружены в регистры (a
иb
).
Заключение
Спецификаторы операндов в GCC встроенном ассемблере играют важную роль в управлении тем, как компилятор обрабатывает операнды в ассемблерных вставках. Понимание этих спецификаторов позволяет писать более эффективный и оптимизированный код, интегрируя ассемблерные инструкции с кодом на C.