Для чего используются "d0" и "d1"?
По сути, это говорит о том, что конечные значения %ecx
, %edi
(при условии 32-разрядного)хранятся в d0
, d1
соответственно.Это служит нескольким целям:
Это позволяет компилятору знать, что в качестве выходных данных эти регистры эффективно перекрываются.Присваивая их временным переменным, оптимизирующий компилятор также знает, что нет необходимости фактически выполнять операцию 'store'.
"= &" определяет их как early-clobber операнды,Они могут быть записаны до того, как все входы будут использованы.Поэтому, если компилятор может свободно выбирать входной регистр, он не должен псевдоним этих двух.
Это технически необязательно для %ecx
, так как он явно назван как вход: "0" (n)
- количество повторений в этом случае.Я не уверен, что это необходимо и для %edi
, поскольку он не может быть обновлен до того, как введен "1" (s)
, и инструкция не выполнена.И опять же, поскольку явно названо как вход, компилятор не может выбрать другой регистр.Короче говоря, «= &» здесь не помешает, но ничего не делает.
Поскольку "a" (c)
указывает только для ввода регистр %eax
, установленный на (c)
, компилятор может предположить, что %eax
все еще содержит это значение после «asm» - что действительно имеет место с "rep; stosb;"
.
"memory"
указывает, что память может быть изменена способом, неизвестнымкомпилятор - что верно в этом случае, он устанавливает (n)
байтов, начиная с (r)
, в значение (c)
- предполагая, что флаг направления очищен, что и должно быть.Это имеет эффект принудительной перезагрузки значений, так как компилятор не может предположить, что регистры отражают значения памяти, которые они должны больше.Это не повредит, и может потребоваться сделать его безопасным для общего случая memset
, но это часто излишне.
Редактировать: Входные операнды могут не перекрывать операнды-сгустки.Не имеет смысла указывать что-то как только для ввода и с засечками .Я не думаю, что компилятор допускает это, и было бы неразумно использовать неоднозначную спецификацию, даже если бы это было так.Из руководства:
Вы не можете писать описание клоббера так, чтобы оно совпадало с операндом ввода или вывода.Например, у вас может не быть операнда, описывающего класс регистров с одним членом, если вы упомянули этот регистр в списке clobber.