有没有一种简单的方法可以在执行完
我希望有类似于在
SHL EAX, CL
指令后检查理论结果(EAX乘以(2的CL次方))是否适合EAX?这个问题是关于无符号整数的。我希望有类似于在
ADD
指令中检查进位标志或在MUL
指令中检查EDX的方法。SHL EAX, CL
指令后检查理论结果(EAX乘以(2的CL次方))是否适合EAX?这个问题是关于无符号整数的。ADD
指令中检查进位标志或在MUL
指令中检查EDX的方法。SHL EAX, CL
将使EAX = 0,进位标志清零。如果输入是EAX = 0x00000000,你将得到完全相同的体系结构结果,包括所有其他标志值。所以即使一个有溢出,另一个没有,事后也无法区分它们。 MOV EBX, 0x80000000
SAR EBX, CL ; now top CL+1 bits of EBX are 1
SHL EBX, 1 ; now top CL bits of EBX are 1
TEST EBX, EAX ; mask off all lower bits
JNZ will_overflow
SHLD
。 MOV EBX, 0x80000000
SAR EBX, CL ; now top CL+1 bits of EBX are 1
MOV EDX, EAX ; copy the input to be shifted
AND EDX, EBX ; mask off all but top CL+1 bits
JZ no_overflow ; top bits all 0
CMP EDX, EBX
JE no_overflow ; top bits all 1
; else handle overflow
SHL EAX, 1
,进位标志确切地指示无符号溢出是否发生。同时,溢出标志指示是否发生了有符号溢出。实际上,CF、OF、ZF、SF、PF这些标志的设置与数学上等效的ADD EAX, EAX
完全相同。因此,如果您更注重节省空间而不是速度,那么您可以考虑使用循环,迭代CL次并在每次迭代中执行SHL EAX, 1
,然后跟随JC overflow_occurred
。test
/jnz overflow
进行每次移位,这是显而易见的最佳选择。对于单个移位,其他策略可能更好或不好,因为它避免了破坏CL中的移位计数,并且避免了在AMD上速度较慢的shld
指令。(此外,对于某些CPU而言,add ebx, ebx
比shl ebx, 1
更便宜,因为add
指令可以在没有移位算术逻辑单元的端口上运行,而我们预计周围的代码至少还有一个移位操作。) - undefined
neg cl
/shr reg,cl
与原始的shl
一起使用,将保留原始shl
移出的位。因此,如果 ZF=1,则表示没有溢出。(但是在第一次移位之前,您需要mov edx, eax
,或者使用BMI2shlx
进行复制和移位)。或者像Jester所说的那样,使用SHLD将位移入一个清零的寄存器,例如xor edx,edx
/shld edx, eax, cl
/ 检查 ZF /shl eax, cl
。在Intel上可能更快,因为shld reg, reg, cl
只需 4 个微操作,而在AMD上,尤其是在Zen 3之前,可能需要更多。这只检查无符号溢出,而不是移出任何设置的位。 - undefineddst + 1
恰好有一个已设置的位呢?但这会忽略dst = 1
但该位是有符号溢出的情况。) - undefined