But there is a simple difference that we don't mind when we using them.
Specially when we are looking into a code in C/C++ source level we miss such things probably.
But more knowledge is better than little knowledge, so I'm going to dig into the situation with you.
In x86/x64 assembly [however today I'm going to use x64 assembly for examples, I suppose most
of our friends are now using x64 machines] there are two shift instructions, one is arthmetic shift and
other is logical shift.
SAR - shift arithmetic right
Example, SAR RAX , 2 will shift 2 positions right and repeat the sign bit 2 wise.
For a example suppose -35 was in the RAX register then before the instruction,
RAX= 1111111111111111111111111111111111111111111111111111111111011101b
in 64 bit binary.
And after the instruction, it may look like this,
RAX= 1111111111111111111111111111111111111111111111111111111111101110b
which is -18
And supposing the same value on RAX register have gone through SHR instruction , then,
before instruction
RAX= 1111111111111111111111111111111111111111111111111111111111011101b
and after the instruction ,
RAX = 0111111111111111111111111111111111111111111111111111111111101110b
which is equivalent to 9223372036854775790, probably the wrong answer.
However our compiler handles this secretly,
Simply when it uses SAR for signed integer shifting and SLR for unsigned shifting.
Here is a example source code that demonstrates it.
Code: Select all
#include <stdio.h>
int main8(int a, unsigned int b){
// logical shift //
int c = a >> 2 ;
int d = b >> 3;
}
Then we generate it's assembly code using the command line '-S' flag.
Code: Select all
$ gcc -S logical_shift_example.c
The resulted assembly instructions are,
Code: Select all
.file "left_shift.c"
.text
.globl main8
.def main8; .scl 2; .type 32; .endef
.seh_proc main8
main8:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
subq $16, %rsp
.seh_stackalloc 16
.seh_setframe %rbp, 16
.seh_endprologue
movl %ecx, 16(%rbp)
movl %edx, 24(%rbp)
movl 16(%rbp), %eax
sarl $2, %eax
movl %eax, -4(%rbp)
movl 24(%rbp), %eax
shrl $3, %eax
movl %eax, -8(%rbp)
addq $16, %rsp
popq %rbp
ret
.seh_endproc
You could see how the compiler have silently choose appropriate instructions as relevant.
NOTE: when going through the assembly listing just ignore .seh_* directives, They are just directives
to the linker to implement seh structured exception handling[http://msdn.microsoft.com/en-us/library ... 85%29.aspx].
--Thanks for reading--