CS 208 w20 lecture 1 outline

1 bitwise operators

  • warmup: what are the four Boolean operations from the reading?
  • take two bit vectors and perform an operation on each corresponding pair of bits (unary operators take just one bit vector)
    • a bit vector (also called a bit array or bit string) is a string of zeros and ones of some fixed length
    • A and B are two bit vectors each 8 bits long: A is 01101001 and B is 01010101
      • & (AND): A & B = 01000001
      • | (OR): A | B = 01111101
      • ^ (XOR): A ^ B = 00111100
        • exclusive-or
        • A ^ A = 00000000
      • ~ (NOT): ~A = 10010110
  • shift operators are slightly different, they slide the bits \(n\) places to the left or right
    • POLL: 0x3<<0x3, 0x1a>>0x2
    • bits that slide "off" are discarded
    • =<<= (left shift): A<<2 = 10100100
      • fill in with zeroes on the right
    • =>>= (right shift): A>>2 = 00011010
      • two versions of right shift
        • logical: always fill in with zeroes on the left

          left_shift.png

        • arithmetic: fill in with copies of the most significant bit

          • from the reading: for a \(w\)-width bit vector \(x\) with bits \([x_{w-1},x_{w-2},\ldots,x_{1},x_0]\), \(x_{w-1}\) is the most significant bit and \(x_0\) is the least significant bit

          right_shift.png

    • shifting multiplies or divides by 2, just like shifting places left or right with decimal numbers multiplies or divides by 10
  • why bitwise?
    • often faster and/or lower power consumption than standard arithmetic operations
    • in low-memory environments, multiple values often packed into the same handful of bytes, use bitwise operations to extract them
  • in C, these operators can apply to any integral data type
    • 1-byte (char) examples:
      • ~0x41 \(\rightarrow\) ~0b01000001 \(\rightarrow\) 0b10111110 \(\rightarrow\) 0xbe
      • ~0x00 \(\rightarrow\) 0xff
      • 0x68 & 0x55 \(\rightarrow\) 0x40
      • 0x68 | 0x55 \(\rightarrow\) 0x7d
      • 0x34<<1 = 0x68
      • 0x68>>2 = 0x1a
      • how many bits are in each of these results?
        • all of them contain 8 bits (1 byte)! zeroes used to "fill out" the fixed length
  • EXERCISE: write C code to extract second most significant byte from a 32-bit integer
    • given x = 0b 01100001 01100010 01100011 01100100 (spaces added to separate bytes), should return 0b 00000000 00000000 00000000 01100010
    • shift and mask: (x>>16) & 0xff

2 logical operators

  • && (and), || (or), ! (not)
  • in C, 0 is false, nonzero is true
  • logical operators can be applied to an integral type, result is always 0 or 1
  • && and || have early termination or short-circuit evaluation (stop evaluating once result is guaranteed)
    • e.g., A && B won't evaluate B when A is false, A || B won't evaluate B when A is true
  • 1-byte (char) examples
    • !0x41 = 0x00
    • !0x00 = 0x01
    • !!0x41 = 0x01
    • 0x68 && 0x55 = 0x01
    • 0x68 || 0x55 = 0x01

3 bits in memory

3.1 memory is a long array of bytes

  • the index or location of a byte in memory is called its memory address
  • the organization of a system's memory is based on the word size
    • among other things, the word size defines the number of bytes in a memory address
      • all memory addresses will be this same fixed length
    • the size of a memory address determines the number of possible addresses (the address space)
    • POLL: if our word size is 4 bits, how big is our address space? (how many different bytes can we refer to with the set of possible addresses)
      • 16 bytes
  • modern systems use 64-bit (8-byte) words, for a potential address space of \(2^{64}\) bytes = 18 billion billion bytes = 18 exabytes

memory_addr_space.png

3.2 data sizes

  • not all data is just a single byte
  • for example, a C int is 32 bits/4 bytes wide
    • what address should we use?
    • any chunk of memory is addressed using the first byte (i.e., lowest memory address)
  • just like we saw that the bit pattern 0x4e6f21 had many different interpretations, the interpretation of data at a memory address depends on both the address and the size
C type bytes (32-bit) bytes (64-bit)
bool 1 1
char 1 1
short 2 2
int 4 4
long 4 8
char * 4 8
float 4 4
double 8 8
  • so a char stored at memory address 0x100 would consist of just the single byte at 0x100
    • QUICK CHECK: for an int stored at this same address, which bytes would it consit of