У меня возникают трудности с пониманием роли, которую играют ограничения в встроенной сборке 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) Есть ли учебник или онлайн-ресурс, в котором более подробно рассматриваются ограничения?