在x86_64 ASM中,以下指令分别执行左移和右移。
SHL rax, cl
SHR rax, cl
我想用Python模拟这些指令。
对于诸如0x613025F862的值,我可以执行以下操作:
result = 0x613025F862 << 0x10
但是,对于更大的值,我得到了不同的结果:
0x60018DDDBD500063 << 0x10
它给我的结果是:0x60018dddbd5000630000。但是,在ASM中,结果将是:0x8dddbd5000630000
我可以通过执行以下操作在Python中获得以上结果:
(0x60018DDDBD500063 << 0x10) & 0xffffffffffffffff
现在,我该如何编写一个能给出正确结果的有效泛型函数?
为此,我编写了如下所示的函数:
def shift_left(input):
result = input << 0x10
if result > 0xffffffffffffffff:
result = result & 0xffffffffffffffff
else:
result = result
return result
谢谢。
答案 0 :(得分:1)
对于可变计数移位,请不要忘记掩盖移位计数。 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中,您可能会发现需要标准化{{1}的输入}可以在shr
范围内进行无符号签名,或者对于0 .. 0xffffffffffffffff
可以将sar
范围内的待签名输入进行标准化。
左移会“溢出”并设置结果的高位。任何使用带符号的解释查看该值的指令都将其视为负数。 (例如-2^63 .. +2^63-1
,扩展一个操作数sar
或imul ecx
/ test
/其他设置cmp
和SF
的指令。)>
当然,在32位,16位或8位寄存器中,该寄存器的最高位是符号位。