Skip to content
All categories

learning

345 posts

Unsolvable Problems, Part I | Stanford CS103 Lecture 23

This lecture connects returning from r, re, and utm to three self-reference warm-ups, following the official examples and proof obligations.

Unsolvable Problems, Part II | Stanford CS103 Lecture 24

This lecture connects defining and locating halt to why halt is recognizable, following the official examples and proof obligations.

Unsolvable Problems, Part III | Stanford CS103 Lecture 25

This lecture connects the lava diagram's two classification tasks to the deck's operational reading of rice's theorem, following the official examples and proof obligations.

Complexity Theory | Stanford CS103 Lecture 26

This lecture connects decidable does not mean feasible to efficiency requires choosing a resource, following the official examples and proof obligations.

Wrap-Up: Four Foundations and Where to Go Next | Stanford CS103 Course Overview

The final deck reconnects proofs, graphs, automata, and computability, then maps those foundations to Stanford courses that use them.

Reading x86-64 Addressing Modes Without Confusing Addresses and Values | Stanford CS107 Lecture 15

CS107 Lecture 15 decomposes x86-64 mov operands into immediate, register, absolute, indirect, displacement, indexed, and scaled-indexed forms, then unifies pointer dereference and array access with D + R[b] + R[i]×s.

From Subregisters to x86-64 Arithmetic and Logic | Stanford CS107 Lecture 16

CS107 Lecture 16 connects b/w/l/q data widths, subregisters, movs/movz, lea, calling conventions, arithmetic and logic, and shifts through one method: establish operand width before tracing sources, destinations, and real memory accesses.

From Condition Codes to x86-64 Loops | Stanford CS107 Lecture 18

CS107 Lecture 18 connects ZF/SF/CF/OF to cmp, test, signed and unsigned conditional jumps, then reconstructs if statements, loops, dynamic instruction counts, setcc, and cmovcc.

From Multiply and Divide to x86-64 Control Flow | Stanford CS107 Lecture 17

CS107 Lecture 17 completes full-width x86-64 multiplication and division, traces %rip through instruction bytes, and uses direct and indirect jmp to show how execution leaves its default sequential path.

Understanding x86-64 Function Calls and Calling Conventions | Stanford CS107 Lecture 19

CS107 Lecture 19 traces %rsp, push/pop, call/ret, parameters, return values, stack locals, and caller/callee register discipline to build the ABI contract that preserves data and control across functions.

From C to x86-64, Reading Disassembly for the First Time | Stanford CS107 Lecture 14

CS107 Lecture 14 dissects the ten x86-64 instructions for sum_array: addresses and machine bytes appear on the left, AT&T assembly on the right, and the reader's job is to recover C-level effects from opcodes, operands, registers, and control flow—not to write assembly from scratch.

From String Search to Buffer Overflows—Input Validation Is Not Capacity Checking | Stanford CS107 Lecture 7

CS107 Lecture 7 builds pointer-based string scanning with strchr, strstr, and strspn, then shows why valid content can still overflow a buffer: safety requires input rules, destination capacity, termination, and memory-error detection.

Caching, Memory Hierarchy, and Locality | Stanford CS107 Lecture 25

CS107 Lecture 25 builds the essential cache model from a concise deck: memory access costs are nonuniform, smaller and faster layers retain data likely to be reused, and temporal and spatial locality determine whether a program benefits.

A C String Is Not a Type but a Memory Contract | Stanford CS107 Lecture 6

CS107 Lecture 6 reduces C strings to character arrays, a terminator, and an address: every convenience in strlen, strcmp, strcpy, strncpy, and strcat depends on the caller preserving capacity and termination invariants.

Profile with Callgrind, Then Read What GCC Optimized | Stanford CS107 Lecture 24

CS107 Lecture 24 builds a measurement workflow with matrix multiplication and Callgrind, then examines GCC constant folding, common-subexpression elimination, dead-code elimination, strength reduction, code motion, and recursion-to-loop conversion. Optimization starts with bottleneck evidence.

The Allocator Invariants Behind In-Place realloc | Stanford CS107 Lecture 23

CS107 Lecture 23 advances the explicit free list to in-place realloc: split a useful remainder when shrinking, absorb free right neighbors when growing, and allocate-copy-free only as a fallback, while preserving both the physical heap and logical list.

From Comparators to a Fully Generic Bubble Sort | Stanford CS107 Lecture 13

CS107 Lecture 13 upgrades a Boolean callback to a three-way comparator, then combines void *, element width, and const void * callbacks into a fully generic bubble sort before mapping the design to qsort, bsearch, lfind, and lsearch.

Function Pointers Inject Ordering into Generic C | Stanford CS107 Lecture 12

CS107 Lecture 12 first uses char * for byte-wise generic swap and rotate, then uses a function pointer to separate bubble sort's traversal mechanism from its ordering rule: void * abstracts data types, while callbacks abstract behavior.

How void * Gives C Generics Without Pretending Types Still Exist | Stanford CS107 Lecture 11

CS107 Lecture 11 finishes the heap contracts of calloc, strdup, free, and realloc, then turns several typed swap functions into void * plus a byte count: C generics do not preserve an unknown type; they explicitly transfer responsibility for addresses, widths, and interpretation.

A First Heap Allocator and the Tension Between Speed and Space | Stanford CS107 Lecture 21

CS107 Lecture 21 starts with alignment, throughput, and utilization, then uses a bump allocator and an implicit free list to explain metadata, splitting, placement, internal and external fragmentation, and the need to coalesce freed blocks.