Что делает знак с двумя процентами (%%) в сборке gcc inline?

Я натолкнулся на код, который выглядит так:

asm volatile (
    # [...]
    "movl $1200, %%ecx;"
    # [...]
);

Я знаю, что делает movl $1200, %ecx в x86. но я был смущен тем, почему есть два процента знаков.

Ответ 1

Встроенная сборка GCC использует% 0,% 1,% 2 и т.д., чтобы ссылаться на входные и выходные операнды. Это означает, что вам нужно использовать два %% для реальных регистров.

Для получения дополнительной информации посмотрите howto.

Ответ 2

Это зависит от:

  • если после строки есть двоеточие :, то это extended asm, а %% escape процент, который может иметь особые значения как упоминалось Карлом. Пример:

    int in = 1;
    int out = 0;
    /*out = in*/
    asm volatile (
        "movl %1, %%eax;"
        "movl %%eax, %0"
        : "=m" (out)
        : "m" (in)
        : "%eax"
    );
    assert(out == 1);
    
  • в противном случае это будет ошибка времени компиляции, потому что без двоеточия это basic asm, который не поддерживает переменные ограничения и не нуждается или поддерживает экранирование %1. Например:.

    asm volatile ("movl $1200, %ecx;");
    

    Хорошо работает.

Расширенный asm используется чаще.

Ответ 3

Это помогает GCC различать операнды и регистры. операнды имеют один префикс%. "%%" всегда используется с регистрами.