Chapter 1 A Tour of Computer System

Compilation System

Take C language as an example linux > gcc hello.c -o hello.

  • Pre-processor (cpp)

    Handles include/define, strips off comments and conditional compilation #ifdef

  • Compiler (cc1)

    Scan/parse/semantic check/code gen/opt

  • Assembler (as)

    From assembly to machine code

  • Linker (ld)

    Relocation & reference resolution [重定位 & 引用解析]

Hardware Organization of a System

DMA (Direct Memory Access) is usually used for high-spped and bulk data transfers, controlled by system programmers.

  • System Bus

    Transfer data in fixed-size blocks called words (4/8 bytes on a 32/64 bit system)

Memory Hierarchy

The localities of cache: Temporal Locality & Spatial Locality.

Abstractions in Computer Systems (Virtualization)

Virtualization is often related to multiplicity, fake versions, and sharing.

  • Process & Thread

    Multiple processes can run concurrently on the same system, and each process appears to have exclusive use of the hardware.

    Context switching with OS Kernel.

    A process can actually consist of multiple execution units, called threads. Threads shares the same code and global data.

  • Virtual Memory

    Program Code & Data, Shared Libraries, Heap, Stack, Kernel Virtual Memory from bottom to top.

    • Virtual address space canve greater than the physical memory.

    • Memory serves as a cache for virtaul memory.

    • Support multiprogramming.

    • Allow multiple processes to share data.

  • File

Import Themes

Amdahl's Law (Quantifying the performance improvement ceiling)

Concurrency and Parallelism

  • Concurrency It refers to the general concept of a system having multiple, simultaneous activities, which do not necessarily execute at the same time, but may interleave in time to create the logical impression of simultaneity.

  • Parallelism It refers to the use of concureency to make a system run faster.

ILP and DLP

  • Instruction-Level e.g. Parallelism pipelining, superscalar, out-of-order execution.

  • Data-Level Parallelism e.g. Single Insruction Multiple Data (SIMD), Vector instructions.

Chapter 2 Representing and Manipulating Information

Information Storage

  • Words

    word size virtual address space

  • Addressing and Byte Ordering Big endian & Little endian

  • ABI Application Binary Interface

    It is based on three key components : the computer ISA, the OS, and the calling convention. ABI incompatibility will occur due to differences between operating systems.

Integer Representaions

Sizes of Data Type in C/C++

SignedUnsigned32-bit (Bytes)64-bit (Bytes)
11
22
44
44
88
44
88

Unsigned Encodings

Suppose a vector , then

Two's Complement Encodings

Inverse form (1's Complement) For a negative number, keep the signed the same and invert the rest.
two zero exits & end-round carry out issues (hte end carry-out bit needs to add back to the LSB)

2's Complement For a negative number, keep the sign the same, invert the rest and add 1.

Suppose a vector , then

Conversions between Signed and Unsigned

For a -bit 2's complemetn signed binary numeral system:

  • Minimum , corresponding to binary (A special case that does not satisfy the invert bits and add 1 rule used for other negative numbers).
  • Maximum , corresponding to binary .

Sign Extension

Small to Big

  • Zero extension of unsigned numbers

  • Sign extension of two's complement numbers

    Since , by induction, we can proof it.

Big to Small

Integer Arithmetic

Addition

Additive Inverse

  • For two numbers A, B, the overflow occurs when (NOT (sign_A XOR sign_B)) AND (sign_A XOR new_sign) == 1. (Two operands have the same sign but the result has a different sign.)

  • One Bit Full Adder

  • Carry Lookahead Adder

Multipilication

Division (by a power of 2)

Unsigned numbers use logical shift, while two's complement numbers use arithmetic shift to achieve sign-preserving extension.

Right shift performs integer division by powers of two :

Floating Point

Floating-Point Representation

s (sign) : The number is positive () or negative ().

M (fraction) : A binary fraction.

E (exponent) : weight.

()

CategoryExponent Fraction Value Formula
Normalizedany
Denormalized
Zero
Infinity
NaN (Not a Number)NaN

Comparison (postive number)

FormatMinimumMaximum
Single Precision Normalized







Single Precision Denormalized




Rounding

Round-downRound-upRound-toward-zeroRound-to-even







Non-midpoint round to the nearest representable value
Midpoint choose the one

Floating Point Operations

Lack of Associativity & Lack of Distributivity

Example Questions

Let are of type int, float, double (Their values are arbitrary, except that neither nor equals , , or .). Then:

  • x == (int)(double) x True
  • x == (int)(float) x False (e.g. )
  • d == (double)(float) d False (e.g. )
  • f == (float)(double) f True
  • d*d >= 0.0 True

Precision (IEEE 754-2008 Standard Formats)

FormatSign BitsExponent BitsMantissa Bits
Quad precision115112
Double precision11152
Single precision (FP32)1823
Half precision (FP16)1510
bfloat16
  • Format: 1 sign, 8 exponent, 7 mantissa bits
  • Same exponent range as FP32 (faster computation, lower power, reduces memory footprint, enables larger models)
  • Reduced precision acceptable for AI (AI/LLM is based on predictions – approximation does not require high precision)

FMA/FMAC

Fused Multiply and Add (FMA) or Fused Multiply and Accumulate (FMAC) combines multiply and add in one instruction ().

  1. Partial Product Generation
  2. Partial Product Reduction
  3. Final add together with the last step of reduction
  4. Normalization & Rounding

Use -mfma -ffp-contract=fast to enable FMA.

Chapter 3 Machine-Level Representation of Programs

Machine-Level Representation of Programs

RISC

Principles

  1. Simplicity favors regularity
  2. Smaller is faster
  3. Make common cases fast
  4. Good design demands good compromises

[RSA should be scalable, flexible, and extensible.]

Instruction Types in RV32I

TypesInstructions
ALUadd, sub, and, or, xor, slt, sltu, sll, srl, sra, and all with immediate (No subi in RV32I)
Control Instructionsbeq, bne, blt, bge, bltu, bgeu, jal, jalr
Memory Instructionslw (No lwu in RV32I), lh, lb, sw, sh, sb, lbu, lhu
Privileged InstructionsInterrupt, Memory Management, System Calls, Control and Status Registers (CSR), Mode Change
FormatNameInstructions
R-typeRegisteradd, sub, sll, srl, sra, xor, or, and
I-typeImmediateaddi, slli, srli, srai, xori, ori, andi
I-typeLoadlb, lh, lw, lbu, lhu
I-typeJump and Link Registerjalr
S-typeStoresb, sh, sw
B-typeBranchbeq, bne, blt, bge, bltu, bgeu
U-typeUpper Immediatelui, auipc
UJ-typeUnconditional Jumpjal
  • Three operand instruction format.

  • X0 is always zero.

  • 32 means Address cability/Integer register length.

  • Immediate

    • type No immediate.
    • type 12 bits immediate. Shift instructions are I-type but repurpose the immediate field as a 5-bit shift amount for RV32I (6-bit for RV64I). inst[30] distinguishes arithmetic from logical right shift, while inst[31:26] are fixed to zero except inst[30] (Range: ).
    • type The 12‑bit immediate is split into high 7 bits (immediate) and low 5 bits (immed). (maintain regularity)
    • type 20 bits immediate.
  • LUI loads a 20‑bit immediate into the upper bits of a register; AUIPC adds a 20‑bit immediate to the current PC for position‑independent addressing. (When the lower 12 bits of a 32‑bit constant are , addi sign‑extends them, causing an incorrect result. The assembler automatically adjusts the upper 20 bits when using the li pseudo‑instruction.) (Range: )

  • Jump

    • jal

      • , (Jumps are 2-byte aligned, so last bit is implicit zero).
      • Range: .
      • Beyond 1MB: Use AUIPC + JALR.
    • jalr

      • , ( clears LSB to ensure 2‑byte alignment).
Why do RISC-V loads/stores use base+immediate instead of base+index?
  • Simpler hardware Only one address adder needed, reducing complexity.
  • Faster address generation Immediate available at decode, no wait for index register.
  • Fewer pipeline stalls Early hazard detection reduces bubbles.

Data Alignment

  • No cache line crossing
  • No double TLB (Translation Lookaside Buffer) misses
  • No double page faults come from a single memory instruction execution
  • Better cache line utilization

Stack / Frame Alignments

  • Defined by ABI (e.g., RISC‑V psABI: 16‑byte)
  • CRT aligns sp before main ()

Compiler Reordering

  • Independent Variables (Rearrangement Allowed)

  • Struct Fields (Rearrangement Forbidden)

    • Binary compatibility
    • Pointer arithmetic
    • Interoperability

PC-relative Addressing

Branch instructions use PC‑relative addressing with a 12‑bit signed offset (in 2‑byte units). Since branch targets are always multiples of 2, encoding in 2‑byte units doubles the reachable range without losing information.

Calling Convention

RV RegistersABI NameCaller/CalleePurpose
x0zeroAlways zero
x1raCallerReturn address
x2spCalleeStack pointer
x3gpGlobal pointer (not used in typical code)
x4tpThread pointer (TLS)
x5–x7t0t2CallerTemporary registers
x8s0 / fpCalleeSaved register / Frame pointer
x9s1CalleeSaved register
x10–x11a0a1CallerArguments / Return values
x12–x17a2a7CallerArguments
x18–x27s2s11CalleeSaved registers
x28–x31t3t6CallerTemporary registers

Leaf routines use args & caller‑saved only (no save/restore).

CISC

Size of Data Type in IA32

C declarationIntel data typeAssembly-code suffixSize (bytes)
Byte
Word
Double word
Quad word
Quad word
Single precision
Double precision

Register

Operands

  • Immediate

  • Register

  • Memory Reference Immediate & Base Register & Index Register & Scale Factor (1,2,4,8)

TypeFormOperator ValueName
ImmediateImmediate
RegisterRegister
MemoryScaled Indexed
MemoryAbsolute
MemoryIndirect
MemoryBase + Displacement
MemoryIndexed
MemoryIndexed
MemoryScale Indexed
MemoryScale Indexed
MemoryScale Indexed

Operation code

  • Movement

    • [movb, movw, movl, movq, movabsq]

      Source operand (Immedita, Register, Memory); Destination operand (Register, Memory)

      Two operands of a move instruction cannot both be memory references. (It is necessary to first move the source memory reference into a register, and then move it to the destination memory reference.)

      movl writes 32 bits of data to the lower half and then automatically zero-extends the value into the upper 32 bits. (In x86-64, any instruction that generates a 32-bit result for a register will set the upper 32 bits of that register to zero.)

      movq can only be 32 bits (sign-extended to 64 bits), whereas movabsq can be 64-bit but the destination must be a register.

    • [movzbw, movzbl, movzwl, movzbq, movzwq]

      movzlq does not exist because of movl instruction.

    • [movsbw, movsbl, movswl, movsbq, movswq, movslq, cltq]

      cltq same as movslq %eax, %rax

  • Stack

    let a quad number be the example

    • subq $8 %rsp
      movq %rbq,(%rsp)
      
    • movq (%rsq),%rax
      addq $8, %rsp
      

Load Effective Address

Computes effective address and stores it in destination register

Unary Operations

InstructionsEffect
inc D
dec D
neg D
not D

Binary Operations

InstructionsEffect
add S D
sub S D
imul S D
xor S D
or S D
and S D

Shift Operations

InstructionsEffect
sal D
shl D
sar D Arithmetic Right Shift
shr D Logical Right Shift

Shift instructions can shift by an immediate value, or by a value placed in the single-byte register %cl.

Condition Code

  • Carry Flag [check for overflow in unsigned operations]

  • Zero Flag

  • Sign Flag

  • Overflow Flag

  • Similar to sub, but it only sets the condition codes without changing the value of the destination register.

    When S == D, .

    It will set the condition codes based on the result of .

  • Similar to and, but it only sets the condition codes without changing the value of the destination register.

    When S & D == 0, .

Set Instructions

InstructionEffectDescription
sete D
setne D
sets Dnegative
setns Dnonnegative
setg DSigned
setge DSigned
setl DSigned
setle DSigned
seta DUnsigned
setae DUnsigned
setb DUnsigned
setbe DUnsigned

Jump Instructions

InstructionJump ConditionDescription
jmp LabelDirect Jump
jmp *OperandIndirect Jump
je Label
jne Label
js LabelNegative
jns LabelNonnegative
jg LabelSigned
jge LabelSigned
jl LabelSigned
jle LabelSigned
ja LabelUnsigned
jae LabelUnsigned
jb LabelUnsigned
jbe LabelUnsigned

Conditional Move Instructions

InstructionMove ConditionDescription
cmove S, R
cmovne S, R
cmovs S, RNegative
cmovns S, RNonnegative
cmovg S, RSigned
cmovge S, RSigned
cmovl S, RSigned
cmovle S, RSigned
cmova S, RUnsigned
cmovae S, RUnsigned
cmovb S, RUnsigned
cmovbe S, RUnsigned

Loop

do-while, while, and for loops can be implemented by combining conditional tests and jumps.

Switch

switch is compiled into a jump table. The execution time of the switch statement is irrelevant to the number of cases.

Transfer Control

InstructionDescription
call LabelProcedure Call (Direct)
call *OperandProcedure Call (Indirect)
retReturn from Procedure Call

Data Transfer

The registers' names depend on the size of the data type being passed.

If a function has more than 6 integer parameters, the additional arguments must be passed on the stack. Note that the argument 7 is located at the top of the stack. All stack-passed arguments are aligned to multiples of 8 bytes.

Pointer

ExpressionTypeValueAssembly Code
Eint*movq %rdx, %rax
E[i]intmovl (%rdx, %rcx, 4), %eax
&E[i]int*leaq 8(%rdx, %rcx, 4), %rax
&E[i] - Elongmovq %rcx, %rax

Notes:

  1. &E[i] - E yields type long (specifically ptrdiff_t) because pointer subtraction returns the number of elements between them as a signed integer.

  2. int* uses movq (not movl) because pointers are 64-bit addresses in x86-64.

Nested Arrays

T D[R][C] , is the size of data type T in bytes.

Struture & Union

Structure

Types

Notes:

  1. The address of any K-byte basic object must be a multiple of .

  2. The offset of the first member is always 0 in a structure.

  3. The compilers probably add some bytes at the end of a structure to ensure that each element in an array of structures could satisfy its alignment requirements.

Union

The total size of a union equals the size of its largest field.

Application

Buffer Overflow

Three protection mechanisms to thwart buffer overflow attacks:

  • Stack Randomization Address-Space Layout Randomization (ASLR)

  • Stack Corruption Detection Place a random canary value between local buffers and critical stack data to detect buffer overflows.

  • Limiting Executable Code Regions

Dynamic Stack Frame

%rbp is base pointer/frame pointer dynamic stack frame

Floating-point Code

Chapter 4 Processor Architecture

Logic Design and Hardware Control Language (HCL)

Logic Gate

CMOS

Process

For Y86-84 :

  1. Fetch

    • Read instruction bytes from memory using PC:
      • icode:ifun (instruction specifier)
      • rA, rB (register specifiers)
      • valC (8-byte constant)
    • Compute next instruction address → valP
  2. Decode

    • Read up to two operands from registers
    • rA, rBvalA, valB
    • For popq, pushq, call, ret: also read from %rsp
  3. Execute

    • Compute (ALU/address/stack) → valE
    • Set condition codes
    • Conditional moves: check CC, update dest register
    • Jumps: decide branch
  4. Memory

    • Write to memory
    • Read from memory → valM
  5. Write Back

    • Write up to two results to registers
  6. Update

    • Set PC to next instruction address

Pipelining

  • Throughput the number of instructions in one second.

    GIPS: Giga-Instructions Per Second

  • Circuit Retiming

    Repositions registers within a design to optimize performance or area, without altering the system’s input/output behavior. It changes the state encoding by moving delays (registers) across combinational logic elements.

Hazards

The dependency between instructions may lead to incorrect computation results.

Data Hazards

  • Stalling

    Stalling prevents data hazards by pausing the pipeline until required operands are ready. This approach is simple but reduces performance.

  • Data Forwarding (Bypassing)

    Data forwarding allows a result computed in a later pipeline stage to be passed directly to an earlier stage as a source operand.

  • Load/Use Hazards

    A load/use hazards occurs when an instruction requires a value that is still being loaded from memory by the previous instruction. Since the memory read completes late in the pipeline, forwarding cannot resolve the dependency in time, causing a stall.

Control Hazards

Control hazards occur when the processor cannot determine the next instruction's address during the fetch stage. In a pipelined processor, this typically happens for ret instructions and mispredicted conditional jumps.

  • ret Inserting bubbles to wait for the return address to be determined.

  • Conditional Jump Branch mispredictions are handled by cancelling the erroneously fetched instructions through the insertion of pipeline bubbles (or via instruction squashing) in the decode and execute stages.

Pipelined Y86-64 Implementations

Fetch Stage

  1. Sequential Execution

halt, nop, rrmovq, irmovq , mrmovq, Opq, pushq, popq, covXX, addq

  1. Jump Execution

call, jxx (The Select PC mechanism is employed to correct branch mispredictions.)

  1. ret

Decode Stage

The selection logic chooses between the merged valA/valP signals and one of five forwarding sources (e_valE, m_valM, M_valE, W_valM, or W_valE) based on the instruction type and hazard detection. If no forwarding is triggered, d_rvalA (the register file read) is used as the default value.

Pipeline Control Logic

  • Stall

    Keep the state of the pipeline registers unchanged. When the stall signal is set to 1, the register will retain its previous state.

  • Insert Bubbles

    Setting the state of the pipeline registers to a value equivalent to a nop instruction. When the bubble signal is set to 1, the state of the register will be set to a fixed reset configuration.

Load/Use Data

A one-cycle pipeline stall is required between an instruction that reads a memory value in the execute stage and a subsequent instruction that uses that value in the decode stage.

Mispredicted Branches

When a branch is mispredicted as taken, the pipeline must squash the incorrectly fetched instructions from the target path and redirect fetching to the correct fall-through address.

Processing ret

The pipeline must stall until the ret instruction reaches the write-back stage.

Exception Handling

When an instruction triggers an exception, all subsequent instructions must be prevented from updating programmer-visible state, and execution must halt once the exception-causing instruction reaches the write-back stage.

ConditionFDEMW
Handling retStallBubbleNormalNormalNormal
Load/Use HazardStallStallBubbleNormalNormal
Mispredicted BranchNormalBubbleBubbleNormalNormal

Chapter 5 Optimizing Program Performance

Capabilities and Limitations of Optimizing Compilers

Memory Aliasing

The two pointers probably reference the same memory address.

Function Calls

Performance

CPE: Cycles Per Element.

Understanding Modern Processors

Instruction Control Unit (ICU) & Execution Unit (EU)

The ICU reads instructions from the instruction cache and uses branch prediction to speculatively fetch and decode future instructions in advance. This speculative execution mechanism allows the processor to start executing operations along the predicted program path before the actual branch outcome is known. If the prediction is incorrect, all speculative results are discarded and execution restarts from the correct branch target.

Decoded instructions are broken down into micro-operations, which are then sent to the EU for execution. The EU includes arithmetic units and dedicated load/store units, each with address calculation logic, to perform memory operations via the data cache.

All along, the retirement unit tracks instruction progress to ensure sequential program semantics are preserved. Instructions remain in a queue until their results are ready and all relevant branch predictions are verified. Only then are results committed to the architectural registers. If a branch was mispredicted, the affected instructions are flushed and their results discarded, preventing any erroneous state change in the program.

Register renaming allows out-of-order execution by assigning unique tags to instruction results. When a later instruction needs a register value, it uses the tag to get the result directly once ready, avoiding waits for register writes and enabling speculative execution.

Each operation is characterized by the following metrics:

  • latency It represents the total time required to complete the operation.

  • Issue time It indicates the minimum number of clock cycles needed between two consecutive operations of the same type.

  • Capacity It refers to the number of functional units capable of executing that operation.