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 using msvc, // is the assembly for that C statement.
Why is signed int /=2
is different from >>=1
? What are cdq
and sub
doing? Are they necessary?
Dividing a negative integer by 2 is not the same as shifting it to the right by 1. For example
-7 / 2 = -3
With shifts:
11111001b >> 1 = 11111100b which is -4
Thus the compiler has to take care of the case when the integer is negative
What are cdq and sub doing? Are they necessary?
cdq
performs the following EDX:EAX ← sign-extend of EAX.
Thus if the value in EAX is negative, EDX will get 0xFFFFFFFF (which is -1), otherwise it will be 0 (due to the sign extension of EAX).
sub eax, edx ; will either result in 'eax - 0' (if EAX is positive) or
; 'eax - (-1)' (if EAX is negative)
Which in case of the above example will normalize the -7 to -7 - (-1) = -6
and then -6 >> 1 = -3
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With