Пояснение % %

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”

  • Описание: Указывает на регистр eax (или rax в 64-битных системах).
  • Пример: [val] "a"(value)

Пример использования:

int value = 5;
__asm__(
    "mov %[val], ebx;"
    :
    : [val] "b"(value)
    : "ebx"
);

Здесь %[val] указывает на переменную value, которая загружается в регистр ebx.

7. “c”

  • Описание: Указывает на регистр ecx (или rcx в 64-битных системах).
  • Пример: [val] "c"(value)

Пример использования:

int value = 25;
__asm__(
    "mov %[val], edx;"
    :
    : [val] "d"(value)
    : "edx"
);

Здесь %[val] указывает на переменную value, которая загружается в регистр edx.

9. “S”

  • Описание: Указывает на регистр esi (или rsi в 64-битных системах).
  • Пример: [src] "S"(source)

Пример использования:

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.