Arithmetic shift and logical shift

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/Tree_in_sea/article/details/100575247

Arithmetic shift and logical shift

unsigned int i = 8;

int main () {

<<. 3 I = I; // output i = 64

}

Above the variable i is the use of logical shift or arithmetic shift it?

Logical shift, simple understanding is physically move around performed bitwise, two supplemented with 0, do not care about the sign of a problem

Arithmetic shift left and right bit is also performed on the physical movement of two supplemented with 0, but it must ensure that the sign bits are not changed

But we are curious "i << 3" and "i >> 3" in the end uses arithmetic or logical shift it? In fact, a single may not have much break from the C language itself, because C will eventually be compiled into assembly code for the target platform compiler, it is necessary to combine compiler and assembler program to analyze the code above, the following analysis mainly from the disassembly start , about the shift of instruction under the ARM platform are:

LSL (logical shift left)

The LSR (Logical shift right)

ROR (Rotate Right)

ASL (Arithmetic Shift Left)

ASR (arithmetic shift right)

RRX (with extended cyclic right)

 

Let us look at the results disassemble those above C program:

 

 

Conclusion: Description unsigned number is used in a logical shift left.

So after testing we found several cases the following code compilation, and the result is the same as above, are logical left:

signed int i = 8;

int main ()

{

<<. 3 I = I; // output i = 64

}

signed int i = -8;

int main ()

{

<<. 3 I = I; // output i = -64

}

Conclusion: The described type, whether signed or unsigned, regardless of the positive and negative values, are used in a logical shift left.

Then take a look right:

unsigned int i = 8;

int main ()

{

= I. 3 >> I; // output i = 1

}

Disassembly results:

 

 

Conclusion: Description unsigned right shift logic is employed.

Look at the number of signed right shift operation:

signed int i = 8;

int main ()

{

= I. 3 >> I; // output i = 1

}

Disassembly results:

 

CONCLUSION: Description signed numbers using the arithmetic right.

After testing found that the situation following code disassembly results and the above is the same:

signed int i = -8;

int main ()

{

= I. 3 >> I; // output i = -1

}

Conclusion: Description As long as there is a symbolic number, regardless of the value is positive or negative, are used when the right arithmetic shift right.

Question: According to the principle of zero shift up, why are logical shift left it?

Q: first look "-8" and "8" value in the computer memory are:

0xfffffff8

0x8

Because computers are by complement value stored code, so regardless of positive or negative sign, the sign bit left shift does not produce for the impact, and the right is different, not how unsigned shift right sign bit, but the number of logical symbols the high bit of 0, the sign bit to the right, so that only the arithmetic shift right.

Summary: Only signed right before the arithmetic right shift, or other cases have adopted a logical shift operations (logical left or logical shift right). As long as the computer is turned complement understand the way to save the value, it's all clear.

 

 

Guess you like

Origin blog.csdn.net/Tree_in_sea/article/details/100575247