SF и ZF устанавливаются на основе только результата, а не входов.
SF является старшим битом результата, поэтому (для интерпретации битового шаблона с добавлением 2) это означает, что результат отрицательный.
SF = ((signed)result < 0);
ZF = (result == 0);
Вы также можете сказать, что ZF - это горизонтальное ИЛИ всех битов, инвертированных. (Это очищается, если есть один установленный бит).
Конечно result
- это 8, 16, 32 или 64 бита, в зависимости от размера операнда. Флаги устанавливаются на основе старшего бита и нуля фактического вывода, а не полного регистра, частью которого он является, для такой инструкции, как neg al
.
Конечно, не все инструкции устанавливают все флаги , например, inc
/ dec
famously оставляют CF без изменений, устанавливая остальные обычным способом, делая его пригодным для использования внутри adc
петли.
Вращает только набор CF и (для неявного кода операции shift-by-1) также OF. SF / ZF / PF остаются неизмененными, в отличие от регулярных некруглых сдвигов. Если счетчик сдвигов не равен нулю, в этом случае все флаги не изменяются. Это проблематично для выполнения не по порядку сдвигов и поворотов (флаги являются дополнительной зависимостью для сдвигов / поворотов с переменным числом), поэтому BMI2 shlx
/ shrx
быстрее в Intel , И rol
/ ror
являются дополнительными мопами.
BSF / BSR установить ZF на основе входа (не результата) и оставить регистр вывода неизмененным, если вход был нулевым.
Документы Intel в этом случае говорят "undefined", но AMD документирует неизменное поведение, которое фактически реализует все оборудование. Я думаю, что маловероятно, что Intel когда-либо создаст оборудование, которое не реализует неизменное поведение, особенно сейчас, когда BMI1 lzcnt
/ tzcnt
дает нам альтернативу без ложной зависимости. IDK, почему они не просто документируют, как bsf
/ bsr
работают на их оборудовании.