Мне трудно понять роль ограничений во встроенной сборке 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» означает, что она должна быть в памяти - но я на самом деле не понимаю, каковы последствия выбора одной переменной над другой. есть, или почему операция сложения не t работает правильно, если я выберу определенную комбинацию ограничений.
Вопросы: 1) В приведенном выше примере кода, почему ограничение «m» на b
привело к получению c
написано? 2) Есть ли какой-нибудь учебник или онлайн-ресурс, в котором более подробно рассказывается об ограничениях?