Вы используете выходной операнд "=a"
, поэтому компилятор знает, что ваш ассемблер записывает этот регистр.
Он будет планировать соответственно, используя другой регистр для всего, что он хочет сохранить после ассемблера.пробеги.Вы должны точно описать свой asm для компилятора с ограничениями, потому что в противном случае это черный ящик.
Соглашения о вызовах функций практически не имеют значения для встроенного asm.После того, как эта функция встроена, она будет в середине некоторой более крупной функции.
Нет смысла делать это со встроенным asm вместо встроенного в GNU C __atomic_add_fetch
, который скомпилируется в lock xadd
или lock add
в зависимости от того, используется результат или нет.https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html.
Если вы настаиваете на использовании встроенного asm, используйте ограничения "+r"
и "+m"
для двух операндов ввода / вывода, а просто имеют lock xadd
внутришаблон asm.Пусть компилятор сделает все остальное, поэтому напишите это в C (установив вход регистров в 1
перед asm и увеличив его после).Это позволяет компилятору оптимизировать ++
для более поздней операции, если он этого хочет.GCC знает, как поместить 1
в регистр, и как увеличить.
Конечно, gcc также знает, как использовать lock
ed инструкции, поэтому вы должны позволить это делать с помощью встроенных команд.или C ++ 11 std :: atomic.