任何人都可以给我一些想法吗?
代码为:
seg000:3825 some_math_op_on_regs proc far; CODE XREF: sub_72C6+19FP
seg000:3825 ; sub_72C6+1DDP ...
seg000:3825 cmp cl, 10h
seg000:3828 jnb short loc_383A ; Jump if CF=0
seg000:382A mov bx, dx ; c register is < 16; move d to b
seg000:382C shr ax, cl ; Shift a right by value in c (logical)
seg000:382E sar dx, cl ; Shift d right by value in c (arithmetic)
seg000:3830 neg cl ; Negate c (2's complement)
seg000:3832 add cl, 10h ; Add 16 to c
seg000:3835 shl bx, cl ; Shift b left by value in c (logical)
seg000:3837 or ax, bx ; OR a and b, store result in a
seg000:3839 retf
seg000:383A ; --------------------------------------------------------------------
seg000:383A
seg000:383A loc_383A: ; CODE XREF: some_math_op_on_regs+3j
seg000:383A sub cl, 10h ; c register is >= 16; subtract 16 from c
seg000:383D xchg ax, dx ; Switch values in a and d
seg000:383E cwd ; Convert word to doubleword
seg000:383F sar ax, cl ; Shift a right by value in c (arithmetic)
seg000:3841 retf
seg000:3841 some_math_op_on_regs endp
#1 楼
这看起来像一个32位右移编译器助手。在16位时代,32位数字由一对寄存器表示,在这种情况下为ax:dx
。对16的检查是一种优化:如果移位超过16,则低位寄存器的值会完全丢失,因此可以将其丢弃并替换为dx>>(shift-16)
,而高位寄存器将由于cwd
指令的结果而填充符号位。这是Borland C运行时库中的(略加注解)的源代码,似乎与您的源代码相匹配:#2 楼
它似乎是32位右移,其中dx:ax
提供了32位数字,而cl
是要移位的位数。 16位只需要关心存储在cl
中的高16位,因为低16位无论如何都被移出。如果dx
大于16,则将cl
(高16位)移至dx
并将其转换为32位数字,请从ax
中减去16,因为这是通过忽略低16位来隐式完成的,然后将高位部分(即现在的cl
多亏了dx:ax
)的数字。 />基本上,这是在16位架构中完成的32位右移。