То есть, вы хотите сделать 16-битный сдвиг, но установить CF с верха нижней половины?Я не знаю, почему вы этого хотите, особенно если вы собираетесь jnc
вместо использования adc cl, 0
для выполнения CL + = CF.
Существуют более эффективные способы подсунуть высокий клеврегистр, например, сделать копию регистра и фактически сдвинуть биты вместо того, чтобы просто использовать регистр.Или используйте инструкцию popcnt
после выделения этих битов в регистре, если вы можете предположить, что современный процессор.
В любом случае, для этого нет единой инструкции, но есть пара вариантов для установки CFсогласно немного, в зависимости от того, какая совместимость процессора вам нужна.Наиболее простым является:
;; 386 for BT/BTS
shl ax, 1
bt ax, 8 ; set CF from the bit that was previously the top of AL
adc cl, 0 ; CL += CF
Существует также способ, который, вероятно, медленен на старых процессорах: x86 сдвигает / вращает, маскируя счет с &31
(или &63
для 64-разрядных сдвигов), поэтому сдвиги /вращается уже 32-битного может использовать счет, равный размеру операнда, и не считать его равным 0.
rol
устанавливает CF в соответствии с последним битом, который "обернут"вокруг "от высокого до низкого.Счет 8 для 8-битного регистра оставляет его неизменным, а последний бит, вращающийся вокруг, является младшим битом.Кроме того, процессоры до 286 не маскировали счет в любом случае, они просто взяли столько тактов, сколько счетчик смен.(Так что это довольно медленно на старых процессорах без бочкообразного сдвига для вращений с постоянным временем.)
Или, если в разделе Руководство по эксплуатации отражена фактическая реализация 286, вращается до mod size
для фактической работы смены, но проверка count != 0
, чтобы увидеть, устанавливает ли он флаги вообще, основана на count & 1Fh
, а не count mod 8
.И если это так, CF = LSB(dest)
;; 186 for immediate-count shifts/rotates
shl ax, 1
rol ah, 8 ; set CF from the bit that was previously the top of AL
adc cl, 0 ; CL += CF
Очевидно, что проще установить ZF в соответствии с конкретным битом, например,
add ax, ax ; AX <<= 1
test ah, 1 ; ZF = low bit of AH
;test ax, 1<<8 ; ZF = low bit of AH same code size, actually
jz no_increment
inc cl
no_increment:
Но ветвление отстой против adc
.
Обратите внимание, что shl
1 практически не имеет преимуществ, за исключением того, что вы можете использовать его с адресом регистрации.На некоторых процессорах более эффективно использовать add ax,ax
для сдвига влево.Он даже устанавливает CF таким же образом (в соответствии с тем, что ранее было верхним битом).