почему и когда мы должны использовать соответствующие ограничения
Это не тот вопрос, который вы задали; Вы спросили, зачем вообще нужен ввод, что должно быть достаточно очевидно, если вы знаете, что на самом деле означает синтаксис. (То, что "=r"(var)
является чистым выводом, независимо от любого предыдущего значения, которое имела переменная C, как было бы var = 123;
). Итак, "=r"
с инструкцией inc
похож на var = stale_garbage + 1;
Но в любом случае, как я уже говорил, интересным вопросом является ", почему существуют соответствующие ограничения, когда вы можете просто использовать "+r"(var)
для операнда для чтения / записи вместо более сложного синтаксиса ограничения сопоставления?"
Они редко используются; обычно вы можете использовать одну и ту же переменную для ввода и вывода, особенно если у вас есть asm внутри C функции-оболочки . Но если вы не хотите использовать один и тот же C var для ввода и вывода, но по-прежнему нуждаетесь в том, чтобы они выбирали один и тот же регистр или память, тогда вам нужно соответствующее ограничение. Один вариант использования может заключать в себе системный вызов, это один вариант использования; Возможно, вы захотите использовать другую переменную C для номера вызова и возвращаемого значения. (За исключением того, что вы можете просто использовать "=a"
и "a"
вместо ограничения соответствия; у компилятора нет выбора.) Или, возможно, выходной var более узкого или другого типа, чем входной var, может быть другим вариантом использования. .
IIR C, x87 - другой вариант использования; Кажется, я помню, что "+t"
не работает.
Я думаю, что ограничения "+r"
RMW внутренне реализованы как выход со "скрытым" ограничением соответствия. Но в то время как %1
обычно выдает ошибку в шаблоне asm, который имеет только один операнд, если этот операнд является входным / выходным "+something"
, то G CC не отклоняет %1
как слишком большое число операндов. И если вы посмотрите на asm, чтобы увидеть, какой регистр или память он фактически выбрал для этого номера операнда за пределами допустимого диапазона, он совпадает с операндом ввода / вывода.
Так что "+r"
в основном syntacti c сахар для соответствия ограничений. Я не уверен, было ли это новым в какой-то момент, и до G CC версии xy вам приходилось использовать соответствующие ограничения? Нередко можно увидеть примеры учебных пособий, в которых для обоих входных и выходных данных используются ограничения на сопоставление с одинаковыми переменными, которые проще читать с ограничениями "+"
RMW.
Основы:
С ограничения как "a"
и "=a"
вам не нужно нужно соответствующее ограничение; в любом случае у компилятора есть только один выбор. Здесь полезно "=r"
, где компилятор может выбрать любой регистр, и вам нужно выбрать такой же регистр для входного операнда.
Если вы только что использовали "=r"
и Отдельный "r"
ввод, вы бы сказали компилятору, что он может использовать это как операцию копирования и чего угодно, оставляя исходный ввод неизмененным и создавая вывод в новом регистре. Или перезаписать ввод, если он хочет. Это было бы уместно для lea 1(%[srcreg]), %[dstreg]
, но не inc %0
. Последний предполагает, что% 0 и% 1 - это один и тот же регистр, поэтому вам нужно что-то сделать, чтобы убедиться, что это правда!