Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C bitshifting behavior

Tags:

c

I found this example, can anyone explain what's going on here? I'm using LLVM 7.1.

uint8_t a = 0xff;
a = ~a >> 1;
// a = 0b1000000

uint8_t b = 0xff;
b = ~b;
b = b >> 1;
//b = 0

a and b should be equal??

EDIT: Added the disassembly:

testt`main:
    0x100000f70 <+0>:  pushq  %rbp
    0x100000f71 <+1>:  movq   %rsp, %rbp
    0x100000f74 <+4>:  xorl   %eax, %eax
    0x100000f76 <+6>:  movl   $0x0, -0x4(%rbp)
    0x100000f7d <+13>: movl   %edi, -0x8(%rbp)
    0x100000f80 <+16>: movq   %rsi, -0x10(%rbp)
    0x100000f84 <+20>: movb   $-0x1, -0x11(%rbp)
    0x100000f88 <+24>: movzbl -0x11(%rbp), %edi
    0x100000f8c <+28>: xorl   $-0x1, %edi
    0x100000f8f <+31>: sarl   $0x1, %edi
    0x100000f92 <+34>: movb   %dil, %cl
    0x100000f95 <+37>: movb   %cl, -0x11(%rbp)
    0x100000f98 <+40>: movb   $-0x1, -0x12(%rbp)
    0x100000f9c <+44>: movzbl -0x12(%rbp), %edi
    0x100000fa0 <+48>: xorl   $-0x1, %edi
    0x100000fa3 <+51>: movb   %dil, %cl
    0x100000fa6 <+54>: movb   %cl, -0x12(%rbp)
    0x100000fa9 <+57>: movzbl -0x12(%rbp), %edi
    0x100000fad <+61>: sarl   $0x1, %edi
    0x100000fb0 <+64>: movb   %dil, %cl
    0x100000fb3 <+67>: movb   %cl, -0x12(%rbp)
    0x100000fb6 <+70>: popq   %rbp
    0x100000fb7 <+71>: retq   
like image 207
iCaramba Avatar asked Apr 27 '16 12:04

iCaramba


1 Answers

In the first case ~a is promoted to int, so you get:

a = 0xffffff00 >> 1 = 0x7fffff80

which is truncated to 0x80.

In the second case, the truncation happens before the shift, so you get:

b = 0xffffff00

which is truncated to 0x00, and then shifting this gives a result of 0x00.

(Note: the above assumes 32 bit ints, normal 2s complement representation and logical right shifting of signed values.)

like image 150
Paul R Avatar answered Oct 02 '22 20:10

Paul R