Мне сложно понять роль ограничений в встроенной сборке GCC (x86). Я читал руководство, в котором точно объясняется, что делает каждое ограничение. Проблема в том, что, хотя я понимаю, что делает каждое ограничение, я мало понимаю, почему вы должны использовать одно ограничение над другим или какие последствия могут быть.
Я понимаю, что это очень широкая тема, поэтому небольшой пример должен помочь сузить фокус. Ниже приведена простая процедура asm, которая просто добавляет два числа. Если происходит переполнение целых чисел, он записывает значение 1
в выходную переменную C.
int32_t a = 10, b = 5;
int32_t c = 0; // overflow flag
__asm__
(
"addl %2,%3;" // Do a + b (the result goes into b)
"jno 0f;" // Jump ahead if an overflow occurred
"movl $1, %1;" // Copy 1 into c
"0:" // We're done.
:"=r"(b), "=m"(c) // Output list
:"r"(a), "0"(b) // Input list
);
Теперь это прекрасно работает, за исключением того, что мне приходилось произвольно висеть с ограничениями, пока я не заработал правильно. Первоначально я использовал следующие ограничения:
:"=r"(b), "=m"(c) // Output list
:"r"(a), "m"(b) // Input list
Обратите внимание, что вместо "0" я использую ограничение "m" для b
. У этого был странный побочный эффект: если я скомпилировал флаги оптимизации и дважды вызвал функцию, по какой-то причине результат операции добавления также будет сохранен в c
. В конце концов я прочитал " соответствия ограничений", который позволяет указать, что переменная должна использоваться как как входной, так и выходной операнд. Когда я изменил "m"(b)
на "0"(b)
, он сработал.
Но я не понимаю, почему вы использовали бы одно ограничение над другим. Я имею в виду, да, я понимаю, что "r" означает, что переменная должна находиться в регистре, а "m" означает, что она должна быть в памяти, - но я действительно не понимаю, какие последствия выбора одного над другим, или почему добавление операция работает некорректно, если я выбираю определенную комбинацию ограничений.
Вопросы: 1) В приведенном выше примере кода почему ограничение "m" на b
вызывает c
для записи? 2) Есть ли какой-либо учебник или онлайн-ресурс, который более подробно описывает ограничения?