unsigned int a=200;
//mov dword ptr [a],0C8h
a >>= 1;
//mov eax,dword ptr [a]
//shr eax,1
//mov dword ptr [a],eax
a /= 2;
//mov eax,dword ptr [a]
//shr eax,1
//mov dword ptr [a],eax
int b = -200;
//mov dword ptr [b],0FFFFFF38h
b /= 2;
//mov eax,dword ptr [b]
//cdq
//sub eax,edx
//sar eax,1
//mov dword ptr [b],eax
b >>= 1;
//mov eax,dword ptr [b]
//sar eax,1
//mov dword ptr [b],eax
im使用msvc,//是该C语句的程序集。
为什么对有符号的int /=2
与>>=1
不同? cdq
和sub
在做什么?他们有必要吗?
将负整数除以2不同于将其右移1。例如
-7 / 2 = -3
有班次:
11111001b >> 1 = 11111100b which is -4
因此,当整数为负数时,编译器必须处理这种情况
cdq和sub在做什么?他们有必要吗?
[cdq
执行以下EDX:EAX←EAX的符号扩展。
因此,如果EAX中的值为负,则EDX将获得0xFFFFFFFF(即-1),否则将为0(由于EAX的符号扩展)。
sub eax, edx ; will either result in 'eax - 0' (if EAX is positive) or
; 'eax - (-1)` (if EAX is negative)
在上述示例中,将-4归一化为-4 - (-1) = -3
。
算术右移实际上是除以2,但四舍五入为最接近的较小整数。因此-7 >> 1
为-4
数学除以2会四舍五入为最接近的绝对整数。
该代码正在编译为另一组说明:
mov edx, DWORD PTR x
mov eax, edx
shr eax, 31
add eax, edx
sar eax
mov DWORD PTR x, eax