Muxiao Liu

Computer System: A Programmer's Perspective

Note · published Version: v1.0.1a (historical) Created Dec 7, 2025 Updated Dec 7, 2025 Visibility: public

Computer System: A Programmer's Perspective

CS:APP is a textbook about computer systems through the language C. This is the start of my journey attempting the fundamentals of software, peeling away layers of abstraction in higher-level implementations. My ultimate goal is to build a small but working operating system.

Chapter 1: A Tour of Computer Systems

Omitted

Chapter 2: Representing and Manipulating Information

Mask

& is the bitwise masking operation.

Bitwise Operations & Logic Operations

Bitwise and logical operations differ in their scope. Bitwise operators operate “bitwise”. While logical operators treat entire arguments as a single True or False, if the argument is non-zero or zero.

Logical (English)BitwiseLogical
NOT~!
AND&&&
OR|II
XOR^
For example:
  1. a&!b = 0x00 for any b\ne 0x00.
  2. (~a|~b)\ne ~(a|b) Because | works on both when the two bits are both 1 or either one is 1. It is not distributive.
  3. In fact, ~ is not distributive over any bitwise operations. Some meaningful relations may be & and | are distributive over each other, and (~a^~b)== a^b.
  4. To express the == sign in a==b with bitwise and logical operations: !(a^b)

Shift Operations

<< and >> perform left and right shift to bits. After shifting the data, logical shifts fill the gap with 0s, while arithmetic shifts fill the gap with the most significant bits. There are no left arithmetic shifts (because arithmetic shifts are used the preserve the sign bit). In C standards, there is no constraint over arithmetic or logical shift for signed data (but it does enforce logical shift for unsigned data). In Java, they are specified by <<< for logical and << for arithmetic.

Addition and subtraction has higher precedence than shift.

Note the answer key for practice problem 2.16 in the Global Edition of CS:APP is wrong for some of the arithmetic shifts.

C avoid overflowing when shifting by a k>w. It masks k to only the lower loggwlog_g w bits, that is.

k mod w = k & (w-1)

given w{2nnN}.w \in \{ 2^{n} \mid n \in \mathbb{N}\}.

Comments

Posting anonymously (you can sign in from the top-left corner!)

Diff vs previous (root)

+0 -0



     
    *CS:APP* is a textbook about computer systems through the language C. This is the start of my journey attempting the fundamentals of software, peeling away layers of abstraction in higher-level implementations. My ultimate goal is to build a small but working operating system.
  
     
     
  
     
    # Chapter 1: A Tour of Computer Systems
  
     
    *Omitted*
  
     
     
  
     
    # Chapter 2: Representing and Manipulating Information
  
     
    ## Mask
  
     
    `&` is the bitwise masking operation.
  
     
     
  
     
    ## Bitwise Operations & Logic Operations
  
     
    Bitwise and logical operations differ in their scope. Bitwise operators operate "bitwise". While logical operators treat entire arguments as a single `True` or `False`, if the argument is non-zero or zero.
  
     
     
  
     
    | Logical (English) | Bitwise | Logical |
  
     
    | ----------------- | ------- | ------- |
  
     
    | NOT               | ~       | !       |
  
     
    | AND               | &       | &&      |
  
     
    | OR                | \|      | II      |
  
     
    | XOR               | ^       |         |
  
     
    For example:
  
     
    1. `a&!b = 0x00` for any `b`$\ne$ `0x00`.
  
     
    2. `(~a|~b)`$\ne$ `~(a|b)` Because `|` works on both when the two bits are both 1 or either one is 1. It is not distributive.
  
     
    3. In fact, `~` is not distributive over any bitwise operations. Some meaningful relations may be `&` and `|` are distributive over each other, and `(~a^~b)`$=$ `a^b`.
  
     
    4. To express the `==` sign in `a==b` with bitwise and logical operations: `!(a^b)`
  
     
     
  
     
    ## Shift Operations
  
     
    `<<` and `>>` perform left and right shift to bits. After shifting the data, logical shifts fill the gap with `0`s, while arithmetic shifts fill the gap with the most significant bits. There are no left arithmetic shifts (because arithmetic shifts are used the preserve the sign bit). In C standards, there is no constraint over arithmetic or logical shift for signed data (but it does enforce logical shift for unsigned data). In Java, they are specified by `<<<` for logical and `<<` for arithmetic.
  
     
     
  
     
    Addition and subtraction has higher precedence than shift.
  
     
     
  
     
    Note the answer key for practice problem 2.16 in the Global Edition of *CS:APP* is **wrong** for some of the arithmetic shifts.
  
     
     
  
     
    C avoid overflowing when shifting by a `k>w`. It masks `k` to only the lower $log_g w$ bits, that is.
  
     
    ```c
  
     
    k mod w = k & (w-1)
  
     
    ```
  
     
    given $w \in \{ 2^{n} \mid n \in \mathbb{N}\}.$