Часто, когда вы пишете на ассемблере, интересно посмотреть на возможные оптимизации.Используя цикл, вы используете флаги Z и C следующим образом:
MOV AL, <your value>
MOV BL, 8
CLC
Loop:
SBB BL, 0
SHR AL, 1
JNZ Loop
Done:
SBB BL, 0
; result is in BL
HLT
Более быстрый способ на старых процессорах состоит в том, чтобы иметь таблицу 256 байтов и выполнить поиск.Как уже упоминалось vitsoft, на современных процессорах использование инструкции POPCNT, вероятно, является самым быстрым (для подсчета всех битов 64-битного регистра в аппаратном обеспечении требуется один такт).
Теперь, если вам нужно знать,точное время, мой цикл не практичен, потому что он будет варьироваться в зависимости от AL
.Еще один способ сделать это быстро - развернуть цикл:
MOV AL, <your value>
MOV BL, 8
SHR AL, 1 ; 1
SBB BL, 0
SHR AL, 1 ; 2
SBB BL, 0
SHR AL, 1 ; 3
SBB BL, 0
SHR AL, 1 ; 4
SBB BL, 0
SHR AL, 1 ; 5
SBB BL, 0
SHR AL, 1 ; 6
SBB BL, 0
SHR AL, 1 ; 7
SBB BL, 0
SHR AL, 1 ; 8
SBB BL, 0
HLT
Это практично, потому что у вас ноль ветвей.Современные процессоры так любят (хотя в данном случае, поскольку мы имеем дело только с 2 регистрами, я не думаю, что это огромное преимущество).