Для сдвигов с переменным числом не забывайте также маскировать число сдвигов.shl
/ shr
смотрите только младшие биты cl
.То же самое для bts reg,reg
или reg,imm
и для BMI2 shlx r64, r64/m64, r64
.
Либо cl & 0x3f
для 64-битных смен, либо cl & 0x1f
для 32, 16 или 8-битных смен.(Таким образом, 16- и 8-битные сдвиги могут обнулять 8- или 16-битный регистр, сдвигая все биты).См. Раздел «Эксплуатация» руководства для псевдокода: http://felixcloutier.com/x86/SAL:SAR:SHL:SHR.html
Вам не нужно делать условное маскирование
result = (input << 0x10) & 0xffffffffffffffff
or
result = (input << (cl & 0x3f)) & 0xffffffffffffffff
Python2 имеетЦелочисленный тип фиксированной ширины, который неявно отбрасывает старшие биты для вас, но Python3 этого не делает.
Для сдвига вправо вам, вероятно, не нужно маскировать, предполагая, что целочисленные типы Python не превращаются в плавающиеточка или фиксированная точка при сдвиге вправо.
Я также не уверен, как Python обрабатывает целые числа со знаком: shr
сдвигает нули, а sar
сдвигает копии бит знака. В x86 asm -1
и 0xffffffffffffffff
буквально одно и то же (все биты установлены) , поэтому в Python вы можете найти, что вам нужно нормализовать ввод для shr
, чтобы он был беззнаковым в *Диапазон 1032 *, или для sar
нормализуйте вход для подписи в диапазоне -2^63 .. +2^63-1
.
Сдвиг влево может «переполниться» и установить старший бит результата.Любые инструкции, которые смотрят на значение с подписанной интерпретацией, будут видеть его как отрицательный.(например, sar
, расширение с одним операндом imul ecx
или test
/ cmp
/ другие инструкции, которые устанавливают SF
и OF
.)
И, конечно, 32, 16или 8-битный регистр, старший бит этого регистра - бит знака.