Определение блоков __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, может дать неожиданные результаты. (См. раздел Использование и сохранение регистров в встроенной сборке.)

Завершение блока, относящегося только к системам Майкрософт

См. также

Встроенный сборщик