Определение блоков __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
, может дать неожиданные результаты. (См. раздел Использование и сохранение регистров в встроенной сборке.)
Завершение блока, относящегося только к системам Майкрософт
См. также
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по