Давным-давно, но мне, вероятно, понадобится это для моего будущего использования ...
В добавление к прекрасному ответу Криса говорится, что ключ использует модификатор между '%' и номером выходного операнда. Например, "MOV %1, %0"
может стать "MOV %q1, %w0"
.
Я не смог найти ничего в constraints.md, но / gcc / config / i386 / i386.c содержал этот потенциально полезный комментарий в источнике для print_reg()
:
/* Print the name of register X to FILE based on its machine mode and number.
If CODE is 'w', pretend the mode is HImode.
If CODE is 'b', pretend the mode is QImode.
If CODE is 'k', pretend the mode is SImode.
If CODE is 'q', pretend the mode is DImode.
If CODE is 'x', pretend the mode is V4SFmode.
If CODE is 't', pretend the mode is V8SFmode.
If CODE is 'h', pretend the reg is the 'high' byte register.
If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.
If CODE is 'd', duplicate the operand for AVX instruction.
*/
Комментарий ниже для ix86_print_operand()
предлагает пример:
b - вывести имя QImode регистра для указанного операнда.
% b0 напечатает% al, если операнды [0] равны 0. 0. 1019 *
Еще несколько полезных опций перечислены в Шаблон вывода документации GCC Internals :
«% cdigit» может использоваться для замены операнда, который является константой
значение без синтаксиса, который обычно указывает на непосредственный операнд.
«% ndigit» похож на «% cdigit», за исключением того, что значение константы равно
перед печатью отрицается.
ad% adigit ’может использоваться для замены операнда, как если бы это была память
ссылка, с фактическим операндом, рассматриваемым как адрес. Это может быть
полезно при выводе инструкции «адрес загрузки», потому что часто
синтаксис ассемблера для такой инструкции требует, чтобы вы написали
операнд, как будто это ссылка на память.
l% ldigit ’используется для замены label_ref в инструкцию перехода.
‘% =’ выводит число, уникальное для каждой инструкции в
Весь сборник. Это полезно для создания локальных меток
упоминается более одного раза в одном шаблоне, который генерирует
несколько инструкций на ассемблере.
Конструкция '%c2
' позволяет правильно отформатировать инструкцию LEA, используя смещение:
#define ASM_LEA_ADD_BYTES(ptr, bytes) \
__asm volatile("lea %c1(%0), %0" : \
/* reads/writes %0 */ "+r" (ptr) : \
/* reads */ "i" (bytes));
Обратите внимание на важное, но редко документированное «c» в «%c1
». Этот макрос эквивалентен
ptr = (char *)ptr + bytes
но без использования обычных целочисленных арифметических портов выполнения.
Изменить, чтобы добавить:
Выполнение прямых вызовов в x64 может быть затруднено, поскольку для этого требуется еще один недокументированный модификатор: '%P0
' (что, похоже, для PIC)
#define ASM_CALL_FUNC(func) \
__asm volatile("call %P0") : \
/* no writes */ : \
/* reads %0 */ "i" (func))
Модификатор «p» в нижнем регистре, похоже, также работает в GCC, хотя ICC распознает только заглавную букву «P». Более подробная информация, вероятно, доступна по адресу / gcc / config / i386 / i386.c . Поиск "'p'".