Определение блоков __asm как макросов C
Блок, относящийся только к системам Майкрософт
Макросы C предоставляют удобный способ вставки кода сборки в исходный код, но они требуют особой осторожности. поскольку макрос расширяется в одну логическую строку. Для создания безотказных макросов следуйте правилам ниже.
Заключайте блок __asm в фигурные скобки.
Помещайте ключевое слово __asm перед каждой инструкцией по сборке.
Используйте комментарии на языке C старого стиля (/* comment */) вместо комментариев в стиле сборки (; comment) или однострочных комментариев С (// comment).
Чтобы проиллюстрировать вышесказанное, в следующем примере определяется простой макрос.
#define PORTIO __asm \
/* Port output */ \
{ \
__asm mov al, 2 \
__asm mov dx, 0xD007 \
__asm out dx, al \
}
На первый взгляд три последние ключевые слова __asm кажутся излишними. Однако они нужны, поскольку макрос расширяется до одной строки.
__asm /* Port output */ { __asm mov al, 2 __asm mov dx, 0xD007 __asm out dx, al }
Третье и четвертое ключевые слова __asm требуются в качестве разделителей операторов. В блоках __asm в качестве разделителей операторов признаются только символ новой строки и ключевое слово __asm. Поскольку блок, определенный как макрос, является одной логической строкой, необходимо отделить каждую инструкцию с помощью __asm.
Очень важно использовать фигурные скобки. Если опустить их, компилятор может перепутать операторы С и C++ на одной строке справа от вызова макроса. Без закрывающей фигурной скобки компилятор не может определить, где завершается код сборки и где начинаются операторы C или С++ после блока __asm в качестве инструкций по сборке.
Комментарии в стиле сборки, начинающиеся с точки с запятой (;), продолжаются до конца строки. Это вызывает проблемы с макросами, поскольку компилятор игнорирует все после комментария вплоть до конца логической строки. То же самое можно сказать об однострочных комментариях C или C++ (// comment). Во избежание ошибок используйте комментарии на языке C старого стиля (/* comment */) в блоках __asm, определенных как макросы.
Блок __asm, записанный в качестве макроса С, может принимать аргументы. В отличие от обычного макроса C, однако, макрос __asm не может возвращать значение. Невозможно использовать такие макросы в выражениях С или С++.
Следует с особой тщательностью вызывать макросы этого типа. Например, вызов макроса на языке сборки в функции, объявленной с соглашением __fastcall, может дать неожиданные результаты. (См. раздел Использование и сохранение регистров во встроенной сборке.)
Завершение блока, относящегося только к системам Майкрософт