在Python中模拟SHL和SHR ASM指令

时间:2018-12-11 01:04:27

标签: python assembly x86-64

在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

谢谢。

1 个答案:

答案 0 :(得分:1)

对于可变计数移位,请不要忘记掩盖移位计数。 shl / shr仅查看cl的低位。对于bts reg,regreg,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中,-10xffffffffffffffff实际上是同一件事(所有位均已设置),因此在Python中,您可能会发现需要标准化{{1}的输入}可以在shr范围内进行无符号签名,或者对于0 .. 0xffffffffffffffff可以将sar范围内的待签名输入进行标准化。

左移会“溢出”并设置结果的高位。任何使用带符号的解释查看该值的指令都将其视为负数。 (例如-2^63 .. +2^63-1,扩展一个操作数sarimul ecx / test /其他设置cmpSF的指令。)

当然,在32位,16位或8位寄存器中,该寄存器的最高位是符号位。