Ассемблерные вставки в GCC (5 стр)
Автор: FordPerfect
Дополнительно
В этом разделе собраны дополнительные сведения, не попавшие в основные разделы.
Модификаторы операндов
В ассемблерной вставке можно использовать модификаторы, изменяющие смысл (и текстовую подстановку) для операндов.
Пример:
uint16_t num; asm volatile ("xchg %h0, %b0" : "+a" ( num) );
Результат:
xchg %ah, %al
Список модификаторов (подробнее см. https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html (6.44.2.8 x86 Operand Modifiers) и http://locklessinc.com/articles/gcc_asm/ (X86 Operand Modifiers)):
Модификатор | Значение |
z | Суффикс для инструкций (b,w,l,q) исходя из размера аргумента |
Z | То же, но работает и для регистров FPU |
B, W, L, S, T | Явное указание суффикса суффикса для инструкций (b,w,l,s,t) |
b | Младшие 8 бит (al, bl, cl, dl) |
h | Старшие 8 бит (ah, bh, ch, dh) |
w | Младшие 16 бит (ax, bx и т. д.) |
k | Младшие 32 бита (eax и т. д.) |
q | 64 бита (rax и т. д.) |
l | Метка, без пунктуации (например .L2) |
c | Константа без пунктуации (без префикса $) |
a | Скобки вокруг имени регистра (для непрямой адресации) |
A | Звёдочка перед именем регистра (для непрямых переходов) |
p | Имя без пунктуации |
P | Имя без пунктуации (в т. ч. для имён функций) |
X | Добавление префикса $ к имени |
H | Старшие 8 байт SSE переменной |
y | Превращает 'st' в 'st(0)' |
n | Меняет знак константы и подавляет префикс $ |
s | Целочисленная константа с последующей запятой |
t | AVX-версия названия SSE-регистра |
x | SSE-версия названия AVX-регистра |
d | Дублирует операнд |
Примечание: большинство информации в таблице автором данной статьи не проверялось.
Явное указание регистров для переменных
См. https://gcc.gnu.org/onlinedocs/gcc/Explicit-Register-Variables.html .
Пример:
register int foo asm ("eax");
Их семантика имеет неочевидные особенности, подробнее см. в документации.
Довольно странный (более того - сомнительный) пример использования можно найти в:
http://www.flipcode.com/archives/How_To_Read_The_TSC_With_GCC.shtml
Явное указание имён
Документация: https://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html .
Примеры:
int foo asm ("myfoo") = 2;
int func (int x, int y) asm ( "MYFUNC");
Вычисление размера кода
Иногда (например для выбора между ближними/дальними переходами) компилятору нужно оценить размер кода, генерируемого ассемблерной вставкой. Документацию по используемой эвристике см. в https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html .
Недокументированные возможности
Некоторые возможности, не указанные в документации можно узнать из чтения исходного кода GCC. Полагаться на то, что они не изменятся в следующих версиях может быть несколько опрометчиво.
Литература
https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html
http://sourceware.org/binutils/docs-2.26/as/index.html
http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
http://locklessinc.com/articles/gcc_asm/
http://www.ethernut.de/en/documents/arm-inline-asm.html
https://ru.wikipedia.org/wiki/GCC_Inline_Assembly
https://en.wikipedia.org/wiki/X86_assembly_language#Syntax
Зубков С. В. "Ассемблер: Язык неограниченных возможностей" ISBN 5-89818-019-2, ДМК, 1999
30 апреля 2016 (Обновление: 4 мая 2016)