GNU C Basi c встроенные операторы asm (без списков операндов / clobber) не рекомендуются для чего-либо, кроме, возможно, тела функции __attribute__((naked))
. Почему нельзя использовать локальную переменную в GNU C basi c встроенных операторах asm? (глобальные переменные безопасно также нельзя использовать.)
https://gcc.gnu.org/wiki/DontUseInlineAsm говорит видеть ConvertBasicAsmToExtended по причинам, по которым не используются операторы Basi c asm. Вы не можете ничего сделать безопасно в Basi c asm; даже asm("cli");
можно переупорядочить с любыми обращениями к памяти, которые не volatile
.
Если вы вообще собираетесь использовать inline asm (вместо написания отдельного файла) функция в asm, или C с внутренними характеристиками), вам необходимо подробно описать вашу инструкцию asm для компилятора в терминах черного ящика с входными и / или выходными операндами, и / или сгустки. См. { ссылка } для ссылок на руководства, включая некоторые ответы SO об использовании ограничений ввода / вывода.
Тщательно продумайте, прежде чем решить, действительно ли стоит использовать встроенный ассемблер GNU C для чего-либо. Если вы можете заставить компилятор отправлять те же инструкции другим способом, это почти всегда лучше. Встроенная или чистая C позволяет оптимизировать постоянное распространение; встроенный asm не (если вы не делаете что-то вроде if(_builtin_constant_p(x)) { pure C version } else { inline asm version }
).
Синтаксис Intel: в G CC скомпилируйте с -masm=intel
, чтобы ваш шаблон asm был частью Intel- синтаксис .s
, и компилятор подставит операнды в синтаксис Intel. (Например, dword ptr [rsp]
вместо (%rsp)
для "m"(my_int)
).
В Clang я не уверен, что существует какой-либо удобный способ использовать синтаксис Intel в обычных операторах asm.
Существует еще один вариант, если вам не нужен эффективный код (но почему вы используете asm?): clang поддерживает -fasm-blocks
, чтобы разрешить синтаксис, такой как неэффективный стиль MSV C inline asm. И да, здесь используется синтаксис Intel.
Есть ли способ компилировать ie код встроенной сборки в стиле Microsoft на платформе linux? показывает насколько неэффективен полученный код: полон сгенерированных компилятором инструкций для сохранения входных переменных в памяти для блока asm{}
для их чтения. Потому что блоки asm в стиле MSV C не могут делать входы или выходы в регистрах. (Clang не поддерживает метод оставления значения в EAX для вывода одного значения, поэтому вывод также должен быть сохранен / перезагружен.)
Вы не можете указать клобберы для этого, поэтому я предполагаю, что блок asm подразумевает "memory"
clobber, наряду с clobbers на всех записываемых вами регистрах. (Или, может быть, даже просто упомянуть.)
Я бы не рекомендовал это; таким образом, невозможно эффективно обернуть одну инструкцию или несколько инструкций. Только если вы пишете целое l oop, вы можете амортизировать накладные расходы при вводе данных в блок asm{}
.