Сброс младшего установленного бита в asm

#assembly #x86 #bit-manipulation

#сборка #x86 #манипулирование битами

Вопрос:

Ниже приведена функция, которую я придумал, чтобы сбросить младший 1-бит в числе.

 unset_lowest_bit:
    # NUM amp; (NUM-1)
    # All binary digits to the left of the first 1 will remain unchanged, so amp; itself=itself
    # Any zeros to the right of the first 1 will stay zero, since anything amp; 0 = 0
    # And finally, the first 1 will go to zero, since the -1 will eventually need to borrow
    # Up to the first 1 digit
    lea -1(%rdi), %rax
    and %rdi, %rax
    ret
  

Кроме того, что для этого не используется вызов функции, является ли это хорошей реализацией для сброса младшего бита? Или есть инструкция, которая делает это (это кажется довольно нестандартным, поэтому не удалось найти ни одной инструкции).

Комментарии:

1. Опять же, спросите компилятор. Это то, что выделяют gcc и clang (или blsr -march=skylake , например, with). godbolt.org/z/4e8b15 . Многие из этих простых вопросов, на которые может ответить компилятор, кажутся беспорядком при переполнении стека, и, как будто вы не прикладываете особых усилий, прежде чем задавать их. IDK, если было бы лучше объединить несколько битовых взломов в один вопрос; вероятно, нет, за исключением всех связанных set / clear / flip одного бита с помощью bts / btr / btc.

2. Но обратите внимание, что в BMI1 есть еще несколько инструкций с наименьшим установленным битом. Я надеюсь, что вы не собираетесь задавать отдельные вопросы о каждом из них. felixcloutier.com/x86 — все их мнемоники начинаются с bls… Смотрите также en.wikipedia.org/wiki /.

3. @PeterCordes спасибо за отзывы и ссылки. Я попробовал -O3 с компилятором (который дал что-то очень похожее на то, что я просил), но не знал о добавлении в -march=skylake , чтобы получить blsr , спасибо за совет.

4. Вы не упомянули в своем вопросе, что вы уже проверили выходные данные компилятора и обнаружили, что это то, что они сделали. Но да, в общем, если вам интересно, может ли быть новая инструкция, используйте недавнюю -march= , например, skylake, znver2 или даже icelake-client, чтобы узнать, использует ли компилятор другие инструкции. (Если это не так, это не доказательство, что его нет, особенно для инструкций SIMD с автоматической векторизацией.) Это, по сути, единственная неочевидная вещь здесь, и почему я не отклонил вопрос.

Ответ №1:

Для этого есть инструкция, но ее нет в базовом наборе инструкций, она находится в BMI1: blsr

BMI1 реализован Haswell и новее на стороне Intel (за исключением Atom) и Jaguar amp; Piledriver и новее на стороне AMD.

Комментарии:

1. Понятно, спасибо за предложение. Если это достаточно распространено, чтобы быть инструкцией, каково использование сброса младшего установленного бита?

2. @David542 например, перебор установленных битов набора битов или проверка того, является ли число степенью двойки (особенно, если ноль разрешен / игнорируется), его можно использовать в деревьях Фенвика