# Decomp Academy > Decomp Academy is a free, interactive course that teaches matching decompilation of retro games: read the original assembly, write C, and the real period compiler grades it byte for byte. Courses cover GameCube (PowerPC, Metrowerks CodeWarrior) and Game Boy Advance (ARM/Thumb, agbcc). Decomp Academy teaches "matching decompilation": you read the assembly the retail compiler produced, write C, and the original compiler compiles and diffs your code against the target instruction by instruction. When every byte matches, the function is solved. The curriculum takes you from never having read a register to matching real functions from games like Star Fox Adventures and Klonoa: Empire of Dreams. - Audience: programmers learning reverse engineering and decompilation, contributors to retro-game decompilation projects, and anyone curious how C compiles down to machine code. - Format: 755 hands-on lessons across 3 courses, in the browser, free, with no signup required to start. - Topics: PowerPC and ARM/Thumb assembly, application binary interfaces, compiler code generation, integer/float/bitwise idioms, stack frames, globals, the optimizer, and complete real-game functions. ## Key pages - [Start the course](https://decomp-academy.dev/courses/gamecube-c/lesson/foundations-what-is-matching): the first lesson, from zero. - [Playground](https://decomp-academy.dev/playground): compile arbitrary C with MWCC GC/2.0 and inspect the assembly it produces. - [Glossary](https://decomp-academy.dev/glossary): definitions of the PowerPC, ABI, and compiler terms used throughout. ## Curriculum ### GameCube — Decompile GameCube PowerPC assembly back into byte-matching C, graded live by the real Metrowerks CodeWarrior GC/2.0 compiler. #### Warm-up — Learn to read the machine ##### Foundations — What decompilation is, PowerPC registers, and reading MWCC output. - [What Matching Decompilation Is](https://decomp-academy.dev/courses/gamecube-c/lesson/foundations-what-is-matching) — matching, toolchain, workflow, mental-model - [How to Read PowerPC Assembly](https://decomp-academy.dev/courses/gamecube-c/lesson/foundations-reading-assembly) — assembly, registers, instructions, mental-model - [Your First Match](https://decomp-academy.dev/courses/gamecube-c/lesson/foundations-welcome) — registers, return-value, workflow - [Arguments Live in Registers Too](https://decomp-academy.dev/courses/gamecube-c/lesson/foundations-identity) — registers, calling-convention - [Immediates: Math With Constants](https://decomp-academy.dev/courses/gamecube-c/lesson/foundations-immediate) — arithmetic, immediates - [Subtracting a Constant](https://decomp-academy.dev/courses/gamecube-c/lesson/foundations-subtract-const) — arithmetic, immediates - [Multiply by a Small Constant](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-mul-const) — strength-reduction, immediates - [Dividing by a Constant](https://decomp-academy.dev/courses/gamecube-c/lesson/foundations-div-const) — arithmetic, divide - [Negation and the Zero Register](https://decomp-academy.dev/courses/gamecube-c/lesson/foundations-negate) — arithmetic, registers ##### Reading Signatures — No more starter functions — derive the arguments and return type yourself. - [The Band-Aid Comes Off](https://decomp-academy.dev/courses/gamecube-c/lesson/signatures-bandaid) — calling-convention, workflow, mental-model - [Counting the Arguments](https://decomp-academy.dev/courses/gamecube-c/lesson/signatures-counting-args) — calling-convention, registers, arguments - [Read an Argument Off the Registers](https://decomp-academy.dev/courses/gamecube-c/lesson/signatures-arg-registers) — calling-convention, registers, arguments - [Count Them Yourself](https://decomp-academy.dev/courses/gamecube-c/lesson/signatures-derive) — calling-convention, arguments, arithmetic #### Core idioms — Every shape C compiles into ##### Integer Arithmetic — Add, subtract, multiply, divide, immediates and the bit-twiddling idioms. - [On to Arithmetic](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-intro) — arithmetic, mental-model - [Adding Two Registers](https://decomp-academy.dev/courses/gamecube-c/lesson/foundations-add) — registers, arithmetic - [Subtraction Reverses Its Operands](https://decomp-academy.dev/courses/gamecube-c/lesson/foundations-subtract) — arithmetic, operand-order - [An Add Then a Subtract](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-add-sub) — arithmetic, chaining, operand-order - [Two Adds, Reassociated](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-two-adds) — arithmetic, chaining, reassociation - [A Subtract Then an Add](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-sub-add) — arithmetic, chaining, operand-order - [A Three-Instruction Chain](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-add-sub-add) — arithmetic, chaining, operand-order - [Multiplying Two Registers](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-mul) — arithmetic, multiply - [Multiply by a Power of Two](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-mul-const-pow2) — strength-reduction, shifts - [An Affine Expression](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-affine) — arithmetic, strength-reduction, instruction-selection - [Unsigned Divide by a Power of Two](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-div-pow2-unsigned) — strength-reduction, shifts, unsigned - [Signed Divide by a Power of Two](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-div-pow2-signed) — strength-reduction, shifts, signed, rounding - [Division Without a Divide](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-reciprocal-divide) — strength-reduction, divide, optimization - [Real Division](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-div-var) — arithmetic, divide, signed - [Modulo Has No Instruction](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-mod) — arithmetic, modulo - [Multiply Then Add](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-mul-add) — arithmetic, multiplication, chaining - [Precedence Changes the Order](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-add-mul) — arithmetic, multiplication, precedence, chaining - [Two Products, Subtracted](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-two-products) — arithmetic, multiplication, chaining, operand-order - [A Three-Instruction Mixed Chain](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-mul-add-sub) — arithmetic, multiplication, chaining, operand-order - [When a Multiply Is a Shift](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-scale-sum) — arithmetic, multiplication, strength-reduction, chaining - [A Shift Inside a Mixed Chain](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-scale-chain) — arithmetic, multiplication, strength-reduction, chaining - [Divide Then Add](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-div-add) — arithmetic, division, chaining - [When a Divide Is a Shift](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-shrink-sum) — arithmetic, division, strength-reduction, chaining - [A Shift-Divide in a Chain](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-shrink-chain) — arithmetic, division, strength-reduction, chaining - [Divide and Multiply, Then Subtract](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-div-sub-mul) — arithmetic, division, multiplication, chaining, operand-order - [Multiply and Divide Combined](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-mul-add-div) — arithmetic, multiplication, division, chaining, operand-order - [All Four Arithmetic Operators](https://decomp-academy.dev/courses/gamecube-c/lesson/arithmetic-all-four-ops) — arithmetic, multiplication, division, chaining, operand-order ##### Bitwise & Shifts — AND/OR/XOR, masks, shifts, and the rlwinm family MWCC loves. - [Masking Bits With AND](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-and-mask) — bitwise, and, masks - [Combining Bits With OR](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-or) — bitwise, or, immediates - [Flipping Bits With XOR](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-xor) — bitwise, xor, immediates - [Setting a Single Flag Bit](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-set-flag) — bitwise, or, flags - [Clearing a Bit: The rlwinm Surprise](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-clear-flag) — bitwise, and, rlwinm, mwcc-idiom - [Testing Whether a Bit Is Set](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-test-bit) — bitwise, and, rlwinm, masks - [Shifting Left by a Constant](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-shift-left) — bitwise, shifts, rlwinm - [Logical Right Shift (Unsigned)](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-shift-right-unsigned) — bitwise, shifts, unsigned, srwi - [Arithmetic Right Shift (Signed)](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-shift-right-signed) — bitwise, shifts, signed, srawi - [Shifting by a Variable Amount](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-shift-variable) — bitwise, shifts, variable-shift, slw - [Extracting a Bitfield in One rlwinm](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-extract-field) — bitwise, rlwinm, bitfields, instruction-selection - [Packing Two Values with a Shift and OR](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-shift-or-pack) — bitwise, shift, or, chaining - [Merging Two Fields: rlwinm + rlwimi](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-merge-fields) — bitwise, and, or, rlwinm, rlwimi, mwcc-idiom - [Chaining XOR Across Three Values](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-xor-chain) — bitwise, xor, chaining - [Bit Select (Mux): AND, ANDC, OR](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-bit-select) — bitwise, and, andc, or, chaining - [Capstone: Pack Three Values into One Word](https://decomp-academy.dev/courses/gamecube-c/lesson/bitwise-pack-three) — bitwise, shift, or, chaining, capstone ##### Control Flow — if/else, ternaries, switch, and the all-important signed-vs-unsigned compare. - [Returning a Comparison as a Bool](https://decomp-academy.dev/courses/gamecube-c/lesson/control-eq-bool) — comparison, boolean, idiom - [Not-Equal Is Its Own Idiom](https://decomp-academy.dev/courses/gamecube-c/lesson/control-ne-bool) — comparison, boolean, idiom - [If / Else: The Compare Feeds a Branch](https://decomp-academy.dev/courses/gamecube-c/lesson/control-if-else) — if-else, comparison, branch - [Two's Complement, srawi, and andc by Hand](https://decomp-academy.dev/courses/gamecube-c/lesson/control-sign-masks) — twos-complement, srawi, andc, bitwise, sign-mask - [Clamping to Zero, Branchlessly](https://decomp-academy.dev/courses/gamecube-c/lesson/control-clamp-low) — if, clamp, branchless, idiom - [Signed Compare: cmpw](https://decomp-academy.dev/courses/gamecube-c/lesson/control-cmp-signed) — comparison, signed, branch, types - [Unsigned Compare: cmplw](https://decomp-academy.dev/courses/gamecube-c/lesson/control-cmp-unsigned) — comparison, unsigned, branch, types - [Comparing Against a Constant: cmpwi vs cmplwi](https://decomp-academy.dev/courses/gamecube-c/lesson/control-cmp-immediate) — comparison, immediates, signed, unsigned, types - [The Guard Clause / Early Return](https://decomp-academy.dev/courses/gamecube-c/lesson/control-guard) — if, early-return, branch, guard - [Ternary Max](https://decomp-academy.dev/courses/gamecube-c/lesson/control-ternary-max) — ternary, comparison, select - [Ternary Min](https://decomp-academy.dev/courses/gamecube-c/lesson/control-ternary-min) — ternary, comparison, select - [Short-Circuit && and ||](https://decomp-academy.dev/courses/gamecube-c/lesson/control-short-circuit) — boolean, short-circuit, branch, logic - [Switch: The Compare Chain](https://decomp-academy.dev/courses/gamecube-c/lesson/control-switch) — switch, branch, comparison, control-flow - [Clamping Between Two Bounds](https://decomp-academy.dev/courses/gamecube-c/lesson/control-clamp-range) — clamp, if, branch, combining - [The if / else-if Ladder](https://decomp-academy.dev/courses/gamecube-c/lesson/control-nested-ladder) — if-else, nested, branch, combining - [A Range Test with &&](https://decomp-academy.dev/courses/gamecube-c/lesson/control-range-and) — short-circuit, range, boolean, combining - [Rejecting Out-of-Range with ||](https://decomp-academy.dev/courses/gamecube-c/lesson/control-reject-or) — short-circuit, range, boolean, combining - [A Multi-Condition Guard](https://decomp-academy.dev/courses/gamecube-c/lesson/control-guard-or) — guard, short-circuit, early-return, combining - [Capstone: A Guarded, Clamped Update](https://decomp-academy.dev/courses/gamecube-c/lesson/control-capstone-clamp-step) — capstone, guard, clamp, combining, branch ##### Loops — for, while, do-while, induction variables and counted loops. - [The Anatomy of a Counted Loop](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-for-sum) — for-loop, induction-variable, control-flow - [While Is the Same Loop](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-while-equivalence) — while-loop, for-loop, control-flow - [Do-While: The Tightest Loop](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-do-while) — do-while, control-flow, branch-elimination - [Counting Down Is Cheaper](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-countdown) — countdown, induction-variable, immediates - [Walking an Array by Index](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-array-sum) — arrays, indexed-load, addressing - [Finding the Maximum](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-array-max) — arrays, ctr-loop, conditional-update - [Walking a Pointer to a Sentinel](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-strlen) — pointers, sentinel, byte-load - [Breaking Out Early](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-break) — break, early-exit, linear-search - [A Mental Model: The Five Parts of a Loop](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-anatomy-model) — control-flow, break, continue, mental-model - [Strength-Reduced Induction](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-strength-reduction) — strength-reduction, induction-variable, pointers - [A Loop With More Work Inside](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-weighted-sum) — arrays, induction-variable, involved-body - [Nested Loops](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-nested) — nested-loops, multiply, control-flow - [Nesting Over a 2-D Array](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-grid-sum) — nested-loops, arrays, row-major, indexed-load - [When the Inner Bound Follows the Outer](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-triangular) — nested-loops, triangular, control-flow - [Capstone: Counting Pairs in a Grid Scan](https://decomp-academy.dev/courses/gamecube-c/lesson/loops-inversions) — nested-loops, triangular, arrays, conditional-update, capstone ##### Types & Width — u8/s8/u16/s16 loads, sign vs zero extension, and width-driven matching, building up to mixed-width and mixed-sign expressions. - [Loading a Byte](https://decomp-academy.dev/courses/gamecube-c/lesson/types-load-u8) — loads, unsigned, zero-extension - [Loading a Halfword](https://decomp-academy.dev/courses/gamecube-c/lesson/types-load-u16) — loads, unsigned, zero-extension - [Signed Loads Sign-Extend](https://decomp-academy.dev/courses/gamecube-c/lesson/types-load-signed) — loads, signed, sign-extension - [Storing a Byte Truncates](https://decomp-academy.dev/courses/gamecube-c/lesson/types-store-byte) — stores, truncation - [Storing a Halfword](https://decomp-academy.dev/courses/gamecube-c/lesson/types-store-half) — stores, truncation - [u8, Not char (The Spurious extsb)](https://decomp-academy.dev/courses/gamecube-c/lesson/types-u8-not-char) — signed, char, sign-extension, matching-idiom - [Widening: Zero vs Sign Extend](https://decomp-academy.dev/courses/gamecube-c/lesson/types-widen-zero-vs-sign) — widening, sign-extension, zero-extension - [Truncating With a Mask](https://decomp-academy.dev/courses/gamecube-c/lesson/types-truncate-mask) — truncation, masking, rlwinm - [Casts That Sign-Extend](https://decomp-academy.dev/courses/gamecube-c/lesson/types-explicit-cast) — casts, sign-extension, extsb, extsh - [Casting Between Signed Widths](https://decomp-academy.dev/courses/gamecube-c/lesson/types-cast-between-signed) — casts, signed, sign-extension - [The Compare Opcode Follows the Type](https://decomp-academy.dev/courses/gamecube-c/lesson/types-compare-width) — comparison, signed, unsigned, branch - [Bumping a Byte Counter](https://decomp-academy.dev/courses/gamecube-c/lesson/types-counter-increment) — loads, stores, read-modify-write, u8 - [Read, Scale, Truncate](https://decomp-academy.dev/courses/gamecube-c/lesson/types-rmw-scale) — loads, stores, read-modify-write, truncation, u8 - [A Signed Halfword Read-Modify-Write](https://decomp-academy.dev/courses/gamecube-c/lesson/types-rmw-half) — loads, stores, read-modify-write, signed, sign-extension - [Combining Two Widths](https://decomp-academy.dev/courses/gamecube-c/lesson/types-mix-widths) — widening, zero-extension, sign-extension, mixed-width - [Mixed Signedness in One Expression](https://decomp-academy.dev/courses/gamecube-c/lesson/types-mix-signs) — widening, zero-extension, sign-extension, mixed-signedness, operand-order - [Capstone: Widths and Signs in One Function](https://decomp-academy.dev/courses/gamecube-c/lesson/types-capstone) — widening, zero-extension, sign-extension, mixed-width, mixed-signedness, chaining ##### Pointers & Memory — Loads and stores, addressing modes, pointer arithmetic and arrays. - [Dereferencing a Pointer](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-deref) — loads, pointers, memory - [Storing Through a Pointer](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-store) — stores, pointers, memory - [A Constant Index Becomes a Displacement](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-index-const) — loads, addressing, arrays - [Writing at a Constant Index](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-store-index-const) — stores, addressing, arrays - [Pointer Arithmetic Is Scaled](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-arith) — pointers, arithmetic, scaling - [A Variable Index Needs Scaling Then Indexing](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-index-var) — loads, indexed-addressing, scaling - [Byte Arrays Need No Shift](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-u8-array) — loads, indexed-addressing, u8 - [Halfword Arrays Shift by One](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-u16-array) — loads, indexed-addressing, u16, sign - [Walking a String](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-strlen) — loops, pointers, u8 - [Comparing Two Pointers](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-compare) — pointers, comparison, boolean - [Guarding Against NULL](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-null-check) — pointers, branches, null - [Swapping Through Pointers](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-swap) — loads, stores, pointers - [Reading Two Elements and Combining Them](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-sum-two) — loads, arrays, chaining - [Scaling One Element Before Combining](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-weighted-elements) — loads, arrays, multiplication, chaining - [Dereference, Then Compute With an Argument](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-deref-then-compute) — loads, arrays, multiplication, chaining - [Indexing Neighbors From a Computed Offset](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-computed-offset) — loads, indexed-addressing, arrays, chaining - [Combining Two Arrays at the Same Index](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-two-arrays) — loads, indexed-addressing, arrays, chaining - [Capstone: Several Dereferences in One Expression](https://decomp-academy.dev/courses/gamecube-c/lesson/pointers-capstone) — loads, indexed-addressing, arrays, multiplication, chaining ##### Structs, Unions & Bitfields — From single fields up to combining several across nested structs, member arrays, unions, and bitfields. - [Reading a Struct Field](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-read-field) — structs, load, offsets - [Writing a Struct Field](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-write-field) — structs, store, offsets - [Narrow Fields: Byte and Halfword Loads](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-narrow-read) — structs, load, narrow-types - [Storing a Byte Field](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-narrow-write) — structs, store, narrow-types - [Alignment Padding Shifts an Offset](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-padding) — structs, alignment, padding, offsets - [Combining Two Fields](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-sum-fields) — structs, load, offsets, chaining - [Computing Across Three Fields](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-combine-fields) — structs, load, offsets, chaining - [Nested Structs Flatten to One Offset](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-nested) — structs, nested, float-load - [Combining Fields Across Nested Structs](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-struct-of-structs) — structs, nested, offsets, chaining - [Arrays of Structs: Scaling the Index](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-array-index) — structs, arrays, address-arithmetic - [An Array Inside a Struct](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-array-field) — structs, arrays, offsets, chaining - [Unions Overlay the Same Bytes](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-union) — structs, unions, type-punning - [A Single-Bit Flag: li; rlwimi](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-bitfield-set) — structs, bitfields, rlwimi - [Multi-Bit Bitfield Writes](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-bitfield-multi) — structs, bitfields, rlwimi - [Reading a Bitfield: rlwinm Extract](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-bitfield-read) — structs, bitfields, rlwinm - [Walking a Linked List](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-linked-list) — structs, linked-list, loops, pointers - [Calling Through a Function Pointer](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-function-pointer) — structs, function-pointers, vtable, ctr - [Copying a Whole Struct](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-copy-whole) — structs, copy, load, store - [Eight-Byte Alignment Copies Through Float Registers](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-copy-aligned) — structs, copy, alignment, floats - [Big Structs Copy in a Loop](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-copy-large) — structs, copy, loops, optimization - [Combining a Copy With a Field Update](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-copy-chain) — structs, copy, write, chaining - [Capstone: Reading a Whole Struct](https://decomp-academy.dev/courses/gamecube-c/lesson/structs-capstone) — structs, arrays, offsets, chaining, capstone ##### Floating Point — f32 vs f64, frsp, fused multiply-add, and float comparisons. - [Floats Live in a Different Register File](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-add) — floating-point, registers, single-precision - [Single-Precision Multiply](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-mul) — floating-point, multiply, single-precision - [Subtraction Keeps Its Order](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-sub) — floating-point, single-precision, operand-order - [Floating-Point Division Is Real](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-div) — floating-point, divide, single-precision - [Dividing by a Constant Becomes a Multiply](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-div-const-reciprocal) — floating-point, divide, reciprocal, strength-reduction - [Doubles Drop the 's'](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-double-add) — floating-point, double-precision, types - [★ The Spurious frsp: f32 vs double Helpers](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-frsp-highlight) — floating-point, types, frsp, highlight - [Loading a Float Constant from the SDA](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-literal) — floating-point, constants, lfs, sda - [★ Fused Multiply-Add](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-fmadds-highlight) — floating-point, fmadds, fp-contract, highlight - [Integer to Float: The Magic-Number Trick](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-int-to-float) — floating-point, conversion, int-to-float - [Float to Int: fctiwz and the Store/Load Dance](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-float-to-int) — floating-point, conversion, fctiwz, float-to-int - [Comparing Floats: fcmpo Feeding a Branch](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-compare-branch) — floating-point, compare, fcmpo, branch - [Absolute Value and Negation](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-abs-neg) — floating-point, fabs, fneg, sign-bit - [Chaining Two Float Adds](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-two-adds) — floating-point, chaining, single-precision - [Mixing Add and Subtract in One Chain](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-add-then-subtract) — floating-point, chaining, operand-order - [A Weighted Sum Folds Into One fmadds](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-weighted-sum) — floating-point, fmadds, constants, chaining - [The Lerp Idiom — fsubs Feeding fmadds](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-lerp) — floating-point, fmadds, interpolation, chaining - [Two Products Summed — the 2D Dot Product](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-dot-product-2d) — floating-point, fmadds, dot-product, chaining - [Accumulating Three Products — the 3D Dot Product](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-dot-product-3d) — floating-point, fmadds, dot-product, structs - [Picking the Larger: fcmpo + Conditional fmr](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-max-via-compare) — floating-point, fcmpo, fmr, branch - [Clamping Between Two Constants](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-two-sided-clamp) — floating-point, fcmpo, fmr, clamp - [Mixing f32 and f64 — Double Math, then frsp](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-f32-f64-mixing) — floating-point, double-precision, frsp, conversion - [★ Capstone: A Float Step With a Clamp](https://decomp-academy.dev/courses/gamecube-c/lesson/floats-capstone-approach) — floating-point, fmadds, fcmpo, clamp, capstone, highlight ##### Putting It Together — Whole functions that combine arithmetic, bits, control, loops, types, pointers and structs into one realistic body. - [Scale, Then Clamp](https://decomp-academy.dev/courses/gamecube-c/lesson/finale-scale-then-clamp) — finale, arithmetic, clamp, control - [A Masked, Guarded Accumulator](https://decomp-academy.dev/courses/gamecube-c/lesson/finale-masked-guarded-sum) — finale, loops, bitwise, mask, control - [Building a Bitmask in a Loop](https://decomp-academy.dev/courses/gamecube-c/lesson/finale-build-a-bitmask) — finale, loops, control, bitwise, shift - [Sum a Struct Field, Then Clamp](https://decomp-academy.dev/courses/gamecube-c/lesson/finale-struct-field-sum-clamp) — finale, structs, arrays, loops, clamp - [A Guarded Float Accumulator](https://decomp-academy.dev/courses/gamecube-c/lesson/finale-guarded-float-accumulate) — finale, floats, loops, pointers, control #### The real ABI — Frames, globals, optimizer, 64-bit ##### Functions & the ABI — Arg registers, saved registers, stack frames and declaration-order coloring. - [Reaching the Fifth Argument](https://decomp-academy.dev/courses/gamecube-c/lesson/abi-fifth-arg) — calling-convention, registers, arguments - [Floats Use Their Own Registers](https://decomp-academy.dev/courses/gamecube-c/lesson/abi-float-args) — calling-convention, floating-point, registers - [A Leaf Has No Stack Frame](https://decomp-academy.dev/courses/gamecube-c/lesson/abi-leaf-function) — stack-frame, leaf, prologue - [The Stack Frame and the Link Register](https://decomp-academy.dev/courses/gamecube-c/lesson/abi-stack-frame) — stack-frame, prologue, epilogue, link-register, calls - [Marshalling Arguments for a Call](https://decomp-academy.dev/courses/gamecube-c/lesson/abi-arg-marshalling) — calling-convention, calls, arguments - [Surviving a Call: Saved Registers](https://decomp-academy.dev/courses/gamecube-c/lesson/abi-saved-registers) — saved-registers, calls, register-allocation - [Declaration Order Colors the Registers](https://decomp-academy.dev/courses/gamecube-c/lesson/abi-declaration-order) — saved-registers, register-allocation, declaration-order - [Returning a Called Result Directly](https://decomp-academy.dev/courses/gamecube-c/lesson/abi-tail-call) — calls, return-value, calling-convention - [When Arguments Spill to the Stack](https://decomp-academy.dev/courses/gamecube-c/lesson/abi-stack-args) — calling-convention, stack-frame, arguments - [Chaining: Keep a Value, Marshal the Rest](https://decomp-academy.dev/courses/gamecube-c/lesson/abi-keep-and-call) — saved-registers, calls, arguments, chaining - [Chaining: Pipe One Call's Result Into the Next](https://decomp-academy.dev/courses/gamecube-c/lesson/abi-pipe-through) — calls, saved-registers, arguments, return-value, chaining - [Chaining: Two Survivors Feeding a Final Call](https://decomp-academy.dev/courses/gamecube-c/lesson/abi-two-survivors-call) — saved-registers, declaration-order, calls, arguments, chaining - [Chaining: The Whole ABI in One Function](https://decomp-academy.dev/courses/gamecube-c/lesson/abi-finale) — saved-registers, declaration-order, calls, arguments, arithmetic, chaining ##### Globals, the SDA & Pools — r13/r2 small-data addressing, @sda21/@ha/@l relocations, and rodata pools. - [Reading a Global Through the Small Data Area](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-read-int) — globals, sda, sda21, r13 - [Writing a Global](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-write-int) — globals, sda, sda21, store - [The Opcode Follows the Type](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-narrow-type) — globals, sda21, types, lbz, lhz - [A Global Float and the Second Small Data Area](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-read-float) — globals, sda, sda2, float, lfs - [Float Literals Become Pooled Constants](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-float-literal) — globals, sda21, literal-pool, lfs, constants - [Taking an Address: SDA li vs. the @ha/@l Pair](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-address-of) — globals, address-of, sda21, addr16, lis, ha-lo - [Indexing a Global Array](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-array-index) — globals, array, addr16, lwzx, scaled-index - [Read Two Globals, Compute, Write Back](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-read-compute-write) — globals, sda21, chaining, load-compute-store - [A Float Global Times a Pooled Literal](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-float-global-literal) — globals, sda21, literal-pool, float, chaining - [Read Wide, Store Narrow](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-scale-narrow-store) — globals, sda21, types, stb, chaining - [Writing Into a Global Array](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-array-store) — globals, array, addr16, stwx, scaled-index, chaining - [Index an Array, Narrow the Result](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-array-index-narrow) — globals, array, addr16, lwzx, clrlwi, chaining - [Read-Modify-Write an Array Element](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-array-rmw-scalar) — globals, array, addr16, sda21, lwzx, stwx, chaining - [★ A Float Array Element, Scaled Into a Global](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-float-array-literal-scalar) — globals, array, addr16, sda21, literal-pool, lfsx, float, chaining - [★ Capstone: A Lighting-Update Function](https://decomp-academy.dev/courses/gamecube-c/lesson/globals-capstone) — globals, sda21, capstone, mixed-types, highlight ##### Optimization & Scheduling — -O4,p, peephole, instruction scheduling, and the pragmas that bend them. - [What -O4,p Actually Does](https://decomp-academy.dev/courses/gamecube-c/lesson/optimization-o4p) — optimization-level, scheduling, mental-model - [Instruction Scheduling: Hiding Latency](https://decomp-academy.dev/courses/gamecube-c/lesson/optimization-scheduling) — scheduling, latency, pipelining - [The Peephole Optimizer: Dot-Form Merging](https://decomp-academy.dev/courses/gamecube-c/lesson/optimization-peephole-merge) — peephole, dot-form, condition-register - [#pragma peephole off: Unfusing the Merge](https://decomp-academy.dev/courses/gamecube-c/lesson/optimization-peephole-off) — peephole, pragma, dot-form - [#pragma scheduling off: Freezing the Order](https://decomp-academy.dev/courses/gamecube-c/lesson/optimization-scheduling-off) — scheduling, pragma, ordering - [Scheduling Floating-Point Work](https://decomp-academy.dev/courses/gamecube-c/lesson/optimization-fp-scheduling) — scheduling, floating-point, latency - [fp_contract: Fused Multiply-Add](https://decomp-academy.dev/courses/gamecube-c/lesson/optimization-fp-contract) — floating-point, fp_contract, fmadds - [Strength Reduction in a Loop](https://decomp-academy.dev/courses/gamecube-c/lesson/optimization-strength-reduction) — strength-reduction, loops, induction-variable - [Common-Subexpression Elimination](https://decomp-academy.dev/courses/gamecube-c/lesson/optimization-cse) — cse, redundancy, optimization-level - [Chaining: CSE Feeds Strength Reduction](https://decomp-academy.dev/courses/gamecube-c/lesson/optimization-cse-strength) — cse, strength-reduction, chaining - [Chaining: Scheduling Plus a Dot-Merge](https://decomp-academy.dev/courses/gamecube-c/lesson/optimization-schedule-peephole) — scheduling, peephole, dot-form, chaining - [Chaining: FP Scheduling and fp_contract at Arity Three](https://decomp-academy.dev/courses/gamecube-c/lesson/optimization-fp-dot-chain) — scheduling, fp_contract, floating-point, chaining - [Chaining: A Reused Product Inside a Fused Multiply-Add](https://decomp-academy.dev/courses/gamecube-c/lesson/optimization-fp-cse-contract) — cse, fp_contract, floating-point, chaining - [Capstone: Scheduling Meets fp_contract](https://decomp-academy.dev/courses/gamecube-c/lesson/optimization-capstone) — scheduling, fp_contract, capstone, lerp ##### Advanced Idioms — Paired-singles, switch jump tables, enums, and volatile — the master's toolkit. - [Switch: The Jump Table](https://decomp-academy.dev/courses/gamecube-c/lesson/advanced-switch-jumptable) — switch, jump-table, bctr, control-flow - [Table or Chain? The Density Rule](https://decomp-academy.dev/courses/gamecube-c/lesson/advanced-switch-decision) — switch, jump-table, compare-chain, heuristic - [Paired-Single FPR Saves in the Prologue](https://decomp-academy.dev/courses/gamecube-c/lesson/advanced-psq-callee-save) — paired-singles, psq_st, callee-save, prologue, floats - [Where Inline asm{} Earns Its Place: psq_l / psq_st](https://decomp-academy.dev/courses/gamecube-c/lesson/advanced-psq-asm-exception) — paired-singles, asm, intrinsics, psq_l, objdump - [Enums Are int-Sized: Recovery Is Naming](https://decomp-academy.dev/courses/gamecube-c/lesson/advanced-enum-sizing) — enum, enum-int, types, naming - [Volatile Defeats CSE: Two Reads, Two Loads](https://decomp-academy.dev/courses/gamecube-c/lesson/advanced-volatile-cse) — volatile, cse, optimization, loads - [Volatile Hardware Registers](https://decomp-academy.dev/courses/gamecube-c/lesson/advanced-volatile-hwreg) — volatile, hardware-register, vu32, memory-mapped - [Chain: An Enum Switched Through the Table](https://decomp-academy.dev/courses/gamecube-c/lesson/advanced-enum-jumptable) — enum, switch, jump-table, chaining - [Chain: Switch on a Hardware Register](https://decomp-academy.dev/courses/gamecube-c/lesson/advanced-hwreg-switch) — volatile, hardware-register, switch, compare-chain, chaining - [Chain: Enum Guard, Then a Volatile Sum](https://decomp-academy.dev/courses/gamecube-c/lesson/advanced-enum-volatile-guard) — enum, volatile, cse, guard, chaining - [Capstone: A Volatile-Guarded Enum State Machine](https://decomp-academy.dev/courses/gamecube-c/lesson/advanced-state-machine) — switch, jump-table, enum, volatile, state-machine - [Capstone II: Saved Floats Dispatched Through a Switch](https://decomp-academy.dev/courses/gamecube-c/lesson/advanced-psq-switch-combine) — paired-singles, psq_st, callee-save, switch, enum, chaining ##### 64-bit Integers — long long across two registers — carry chains, ABI pairing, downcast fingerprints, and intrinsics. - [Two Registers Make a long long](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-register-pairing) — 64-bit, registers, calling-convention - [Adding 64-bit Integers (addc / adde)](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-add) — 64-bit, arithmetic, carry - [Subtracting 64-bit Integers (subfc / subfe)](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-sub) — 64-bit, arithmetic, borrow - [The Odd-Register Alignment Rule](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-register-alignment) — 64-bit, calling-convention, abi - [The Downcast Fingerprint](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-downcast) — 64-bit, types, detection - [Multiplying 64-bit Integers](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-multiply) — 64-bit, arithmetic, multiply - [Division Calls an Intrinsic](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-divide) — 64-bit, division, intrinsics - [Shifts Call an Intrinsic Too](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-shift) — 64-bit, shifts, intrinsics - [Bitwise Ops Are Just Two Halves](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-bitwise) — 64-bit, bitwise, detection - [Comparing 64-bit Integers](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-compare) — 64-bit, comparison, branchless - [Chaining: Carry Into a Borrow](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-carry-then-borrow) — 64-bit, arithmetic, carry, borrow, chaining - [Chaining: A Bitwise Pair Feeds a Carry Chain](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-bitwise-then-add) — 64-bit, bitwise, arithmetic, carry, chaining - [Chaining: A Downcast Prunes the Chain](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-downcast-chain) — 64-bit, types, detection, chaining, downcast - [Chaining: A Sum Feeds a 64-bit Compare](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-sum-then-compare) — 64-bit, arithmetic, comparison, branchless, chaining - [Chaining: Carry, Borrow, and Mask in One Body](https://decomp-academy.dev/courses/gamecube-c/lesson/int64-three-stage-fuse) — 64-bit, arithmetic, carry, borrow, bitwise, chaining ##### The Whole ABI at Once — Whole realistic function bodies that fuse frames, globals, the optimizer, and 64-bit work — every chapter of the tier converging in one symbol. - [A 64-bit Global Accumulator](https://decomp-academy.dev/courses/gamecube-c/lesson/finale-real-global-carry-chain) — finale, globals, sda21, 64-bit, carry - [Call, Read a Global, Clamp](https://decomp-academy.dev/courses/gamecube-c/lesson/finale-real-framed-global-clamp) — finale, stack-frame, globals, sda21, clamp, control - [Globals, Literals, and the Scheduler](https://decomp-academy.dev/courses/gamecube-c/lesson/finale-real-scheduled-global-fmadds) — finale, globals, sda21, float-literal, fp-contract, scheduling - [★ A Jump-Table of Volatile Reads](https://decomp-academy.dev/courses/gamecube-c/lesson/finale-real-jumptable-volatile-dispatch) — finale, switch, jump-table, enum, volatile, globals, highlight - [★ 64-bit Globals, Downcast, Clamp](https://decomp-academy.dev/courses/gamecube-c/lesson/finale-real-downcast-clamp-finale) — finale, globals, sda21, 64-bit, carry, downcast, clamp #### Proving ground — Real Star Fox Adventures functions, start to finish ##### Real-World Mastery — Authentic Star Fox Adventures functions, from warm-ups to full capstones. - [A Real Setter: State, a Float Nudge, and a Boolean Return](https://decomp-academy.dev/courses/gamecube-c/lesson/mastery-spellstone-setstate) — structs, control-flow, float, boolean-idiom - [Copying a Position With a Bias](https://decomp-academy.dev/courses/gamecube-c/lesson/mastery-fueltank-apply) — structs, float, narrow-types, pointers - [A Flag Toggle Behind a Helper Call](https://decomp-academy.dev/courses/gamecube-c/lesson/mastery-fueltank-tick) — bitmask, control-flow, calls, narrow-types - [Clamping a Float Into Range](https://decomp-academy.dev/courses/gamecube-c/lesson/mastery-clamp-health) — float, control-flow, fcmpo, fmr - [A Loop Over an Event Array](https://decomp-academy.dev/courses/gamecube-c/lesson/mastery-cloudrace-oncomplete) — loops, arrays, calls, bitmask - [Orbital Math: fmadds, fdivs, and Saved Float Registers](https://decomp-academy.dev/courses/gamecube-c/lesson/mastery-asteroid-orbit) — float, fmadds, calls, paired-single - [A Phase State Machine](https://decomp-academy.dev/courses/gamecube-c/lesson/mastery-race-advance) — switch, control-flow, calls, float - [A Per-Frame Update: Rotation, a Flag, and a Branch](https://decomp-academy.dev/courses/gamecube-c/lesson/mastery-spellstone-step) — structs, control-flow, bitmask, calls - [Guarded Hit Detection: NULL Chains and a Type Check](https://decomp-academy.dev/courses/gamecube-c/lesson/mastery-tank-hitdetect) — control-flow, structs, float, calls - [The Capstone: A Full Reset-to-Idle](https://decomp-academy.dev/courses/gamecube-c/lesson/mastery-mine-reset) — calls, structs, float, fmadds, control-flow - [peephole off: When You Must Write the (s16) Cast Yourself](https://decomp-academy.dev/courses/gamecube-c/lesson/mastery-tumbler-integratespin) — peephole, narrow-types, float, fmadds, int-to-float - [Two Running Sums, Woven by Hand: Steering the ,p Scheduler](https://decomp-academy.dev/courses/gamecube-c/lesson/mastery-voxmap-choosedir) — scheduling, instruction-order, accumulation, interleaving - [Param Inversion: Who Gets the Saved Register](https://decomp-academy.dev/courses/gamecube-c/lesson/mastery-targetblock-scorehit) — register-coloring, saved-registers, live-range, calls, narrow-types - [Declaration Order Is Register Order: Coloring Saved Regs by Hand](https://decomp-academy.dev/courses/gamecube-c/lesson/mastery-blend-accumulate) — register-allocation, saved-registers, declaration-order, loops, calls ### Game Boy Advance — Decompile Game Boy Advance ARM7TDMI Thumb code back into byte-matching C, graded in your browser by the real agbcc compiler. #### Warm-up — Learn to read the Thumb machine ##### Foundations — What matching decompilation is, the ARM7TDMI's registers, and reading agbcc's Thumb. - [What Matching Decompilation Is](https://decomp-academy.dev/courses/gba/lesson/gba-foundations-what-is-matching) — matching, toolchain, workflow, mental-model - [How to Read Thumb Assembly](https://decomp-academy.dev/courses/gba/lesson/gba-foundations-reading-thumb) — assembly, registers, thumb, mental-model - [Your First Match](https://decomp-academy.dev/courses/gba/lesson/gba-foundations-welcome) — registers, return-value, workflow - [Arguments Land in r0 Too](https://decomp-academy.dev/courses/gba/lesson/gba-foundations-identity) — registers, calling-convention - [Adding Two Registers](https://decomp-academy.dev/courses/gba/lesson/gba-foundations-add) — registers, arithmetic - [Constants Ride Inside the Instruction](https://decomp-academy.dev/courses/gba/lesson/gba-foundations-immediate) — arithmetic, immediates - [Taking a Constant Away](https://decomp-academy.dev/courses/gba/lesson/gba-foundations-subtract) — arithmetic, immediates - [One Instruction Flips the Sign](https://decomp-academy.dev/courses/gba/lesson/gba-foundations-negate) — arithmetic, registers - [Shifting Is Multiplying](https://decomp-academy.dev/courses/gba/lesson/gba-foundations-shift) — arithmetic, shifts - [When a Constant Will Not Fit](https://decomp-academy.dev/courses/gba/lesson/gba-foundations-big-constant) — immediates, constants, shifts - [The Constant Pool](https://decomp-academy.dev/courses/gba/lesson/gba-foundations-literal-pool) — constants, literal-pool, memory ##### Reading Signatures — The scaffolding comes off: derive the whole function from the assembly. - [The Band-Aid Comes Off](https://decomp-academy.dev/courses/gba/lesson/gba-signatures-bandaid) — calling-convention, workflow, mental-model - [Count the Argument Registers](https://decomp-academy.dev/courses/gba/lesson/gba-signatures-counting) — calling-convention, arguments - [Mind the Gap](https://decomp-academy.dev/courses/gba/lesson/gba-signatures-gaps) — calling-convention, arguments - [A Function That Returns Nothing](https://decomp-academy.dev/courses/gba/lesson/gba-signatures-no-return) — calling-convention, return-value, pointers - [Derive the Whole Thing](https://decomp-academy.dev/courses/gba/lesson/gba-signatures-derive) — calling-convention, arguments, arithmetic #### Core Idioms — Every shape C compiles into on a 16-bit instruction set ##### Arithmetic — Two-operand ALU forms, constant building, and the multiplies gcc takes apart. - [On to Arithmetic](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-intro) — arithmetic, mental-model, strength-reduction - [Sums in Two Operands](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-add) — arithmetic, registers, operand-order - [Order Matters in a Subtract](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-subtract) — arithmetic, operand-order, registers - [Three Operands, Two Instructions](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-chain) — arithmetic, operand-order, expressions - [The Copy That Comes First](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-shuffle) — registers, arithmetic, operand-order - [How Far an Immediate Reaches](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-immediate-range) — immediates, registers, arithmetic - [Constants Built From Two Instructions](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-built-constant) — immediates, constants, shifts - [Constants From the Pool](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-pooled-constant) — constants, literal-pool, immediates - [Multiplying Two Registers](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-multiply) — arithmetic, multiply, registers - [A Multiply That Became a Shift](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-mul-pow2) — multiply, shifts, strength-reduction - [Multiply by Nine, Pay for Two Instructions](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-mul-shift-add) — multiply, strength-reduction, shifts - [The Subtracting Kind](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-mul-shift-sub) — multiply, strength-reduction, shifts - [When gcc Gives Up and Uses mul](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-mul-load) — multiply, strength-reduction, constants - [Product Then Sum](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-mul-add) — multiply, arithmetic, registers - [Parentheses You Can See](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-add-mul) — multiply, expressions, operand-order - [Two Products, One Difference](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-two-products) — multiply, registers, operand-order - [Scale and Offset](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-affine) — strength-reduction, multiply, immediates - [Negation Inside an Expression](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-negate-chain) — arithmetic, strength-reduction, expressions - [Running Out of Registers](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-four-operands) — registers, expressions, multiply - [Capstone: The Whole Chain](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-capstone-chain) — strength-reduction, constants, registers - [Capstone: Pool and Product](https://decomp-academy.dev/courses/gba/lesson/gba-arithmetic-capstone-pool) — literal-pool, multiply, constants ##### The Missing Divider — The ARM7TDMI cannot divide, so every division is a function call — or a shift. - [There Is No Divide Instruction](https://decomp-academy.dev/courses/gba/lesson/gba-division-no-instruction) — division, helper-calls, calling-convention - [Unsigned Has Its Own Helper](https://decomp-academy.dev/courses/gba/lesson/gba-division-unsigned) — division, helper-calls, signedness - [Remainder Is a Different Call](https://decomp-academy.dev/courses/gba/lesson/gba-division-modulo) — division, helper-calls, calling-convention - [Unsigned Remainder](https://decomp-academy.dev/courses/gba/lesson/gba-division-umodulo) — division, helper-calls, signedness - [An Unsigned Divide That Is Free](https://decomp-academy.dev/courses/gba/lesson/gba-division-pow2-unsigned) — division, shifts, strength-reduction - [Signed Needs a Nudge First](https://decomp-academy.dev/courses/gba/lesson/gba-division-pow2-signed) — division, shifts, signedness - [Halving Without a Branch](https://decomp-academy.dev/courses/gba/lesson/gba-division-halve) — division, shifts, register-allocation - [An Unsigned Remainder That Is a Mask](https://decomp-academy.dev/courses/gba/lesson/gba-division-mod-pow2-unsigned) — division, bitwise, literal-pool - [The Signed Remainder's Long Way Round](https://decomp-academy.dev/courses/gba/lesson/gba-division-mod-pow2-signed) — division, shifts, signedness - [A Constant Divisor Is Still a Call](https://decomp-academy.dev/courses/gba/lesson/gba-division-const-nonpow2) — division, helper-calls, constants - [Arithmetic Around the Call](https://decomp-academy.dev/courses/gba/lesson/gba-division-around-a-call) — division, calling-convention, register-allocation - [Two Divides in One Function](https://decomp-academy.dev/courses/gba/lesson/gba-division-two-calls) — division, calling-convention, register-allocation - [The Average Trap](https://decomp-academy.dev/courses/gba/lesson/gba-division-average) — division, signedness, shifts - [Capstone: Quotient and Remainder](https://decomp-academy.dev/courses/gba/lesson/gba-division-capstone) — division, calling-convention, signedness ##### Bits and Shifts — Masks, fields and the packing GBA hardware is built around. - [Masking With and](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-and) — bitwise, immediates, register-allocation - [Setting Bits With orr](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-or) — bitwise, immediates, constants - [Toggling With eor](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-eor) — bitwise, shifts, immediates - [Clearing With bic](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-bic) — bitwise, immediates, register-allocation - [Complementing](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-mvn) — bitwise, complement - [A Mask That Will Not Fit](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-big-mask) — bitwise, constants, immediates - [Shifting Left](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-shift-left) — shifts, bitwise, register-allocation - [Two Ways to Shift Right](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-shift-right) — shifts, signedness, types - [Shifting by a Register](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-variable-shift) — shifts, registers, calling-convention - [Pulling a Field Out](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-extract) — shifts, bitfields, register-allocation - [A Field That Keeps Its Sign](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-extract-signed) — shifts, bitfields, signedness - [Putting a Field Back](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-insert) — bitfields, bitwise, constants - [Testing a Single Bit](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-test) — bitwise, branches, register-allocation - [Packing Two Values](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-pack-two) — bitwise, shifts, constants - [Packing Three](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-pack-three) — bitwise, constants, register-allocation - [Swapping Halves](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-swap-halves) — shifts, bitwise, constants - [Capstone: A BGR555 Colour](https://decomp-academy.dev/courses/gba/lesson/gba-bitwise-capstone-color) — bitwise, shifts, constants ##### Branches and Conditions — Flags nearly everything sets, and the branch shapes gcc 2.9 builds from them. - [Your First Branch](https://decomp-academy.dev/courses/gba/lesson/gba-control-first-if) — branches, control-flow, comparisons - [Two Ways Out](https://decomp-academy.dev/courses/gba/lesson/gba-control-early-return) — branches, control-flow, returns - [If and Else](https://decomp-academy.dev/courses/gba/lesson/gba-control-if-else) — branches, control-flow, returns - [Signed Comparisons](https://decomp-academy.dev/courses/gba/lesson/gba-control-signed-compare) — branches, comparisons, register-allocation - [Unsigned Comparisons](https://decomp-academy.dev/courses/gba/lesson/gba-control-unsigned-compare) — branches, comparisons, types - [Comparing Against a Constant](https://decomp-academy.dev/courses/gba/lesson/gba-control-compare-constant) — branches, immediates, constants - [The Compare That Vanished](https://decomp-academy.dev/courses/gba/lesson/gba-control-flags-for-free) — branches, comparisons, arithmetic - [A Comparison as a Value](https://decomp-academy.dev/courses/gba/lesson/gba-control-bool) — branches, comparisons, control-flow - [Picking One of Two](https://decomp-academy.dev/courses/gba/lesson/gba-control-ternary) — branches, control-flow, constants - [The Larger of Two](https://decomp-academy.dev/courses/gba/lesson/gba-control-max) — branches, comparisons, control-flow - [A Floor](https://decomp-academy.dev/courses/gba/lesson/gba-control-clamp-low) — branches, constants, control-flow - [Both Ends](https://decomp-academy.dev/courses/gba/lesson/gba-control-clamp-range) — branches, control-flow, comparisons - [Short-Circuit and](https://decomp-academy.dev/courses/gba/lesson/gba-control-and-chain) — branches, control-flow, comparisons - [Short-Circuit or](https://decomp-academy.dev/courses/gba/lesson/gba-control-or-chain) — branches, control-flow, comparisons - [A Guard at the Top](https://decomp-academy.dev/courses/gba/lesson/gba-control-guard) — branches, control-flow, register-allocation - [Nested Conditions](https://decomp-academy.dev/courses/gba/lesson/gba-control-nested) — branches, control-flow, comparisons - [A Switch That Is Really Ifs](https://decomp-academy.dev/courses/gba/lesson/gba-control-switch-chain) — branches, control-flow, comparisons - [The Jump Table Appears](https://decomp-academy.dev/courses/gba/lesson/gba-control-switch-table) — branches, control-flow, constants - [Capstone: A State Machine](https://decomp-academy.dev/courses/gba/lesson/gba-control-capstone-state) — branches, control-flow, comparisons ##### Loops — The shapes gcc 2.9 rewrites your loops into. - [The Shape of a Loop](https://decomp-academy.dev/courses/gba/lesson/gba-loops-anatomy) — loops, control-flow, branches - [A Loop With No Guard](https://decomp-academy.dev/courses/gba/lesson/gba-loops-do-while) — loops, control-flow, branches - [Counting Up](https://decomp-academy.dev/courses/gba/lesson/gba-loops-count-up) — loops, registers, strength-reduction - [The Loop That Runs Backwards](https://decomp-academy.dev/courses/gba/lesson/gba-loops-countdown) — loops, strength-reduction, registers - [Summing an Array](https://decomp-academy.dev/courses/gba/lesson/gba-loops-array-sum) — loops, arrays, strength-reduction - [The Post-Increment Load](https://decomp-academy.dev/courses/gba/lesson/gba-loops-ldmia) — loops, arrays, addressing - [A Comparison Inside the Loop](https://decomp-academy.dev/courses/gba/lesson/gba-loops-array-max) — loops, branches, arrays - [Walking Until a Zero](https://decomp-academy.dev/courses/gba/lesson/gba-loops-until-zero) — loops, control-flow, arrays - [Leaving Early](https://decomp-academy.dev/courses/gba/lesson/gba-loops-break) — loops, control-flow, branches - [Two Cursors](https://decomp-academy.dev/courses/gba/lesson/gba-loops-two-arrays) — loops, arrays, registers - [A Loop Inside a Loop](https://decomp-academy.dev/courses/gba/lesson/gba-loops-nested) — loops, control-flow, strength-reduction - [Calling From a Loop](https://decomp-academy.dev/courses/gba/lesson/gba-loops-with-call) — loops, calling-convention, registers - [Loops Over Narrow Data](https://decomp-academy.dev/courses/gba/lesson/gba-loops-narrow-elements) — loops, arrays, types - [A Divide Per Trip](https://decomp-academy.dev/courses/gba/lesson/gba-loops-divide-inside) — loops, division, calling-convention - [Capstone: The Scan](https://decomp-academy.dev/courses/gba/lesson/gba-loops-capstone-scan) — loops, control-flow, arrays ##### Narrow Types — 8- and 16-bit values on a chip with no sign-extend instruction. - [Loading a Byte](https://decomp-academy.dev/courses/gba/lesson/gba-types-load-byte) — narrow-types, loads, pointers - [A Signed Byte Costs Two More](https://decomp-academy.dev/courses/gba/lesson/gba-types-load-signed-byte) — narrow-types, sign-extension, loads - [Loading a Halfword](https://decomp-academy.dev/courses/gba/lesson/gba-types-load-halfword) — narrow-types, loads, addressing - [The Register-Offset ldrsh](https://decomp-academy.dev/courses/gba/lesson/gba-types-load-signed-halfword) — narrow-types, sign-extension, loads - [Storing a Byte](https://decomp-academy.dev/courses/gba/lesson/gba-types-store-byte) — narrow-types, stores, shifts - [Storing a Halfword](https://decomp-academy.dev/courses/gba/lesson/gba-types-store-halfword) — narrow-types, stores, addressing - [A Narrow Argument Arrives Wide](https://decomp-academy.dev/courses/gba/lesson/gba-types-narrow-argument) — narrow-types, calling-convention, sign-extension - [Narrowing on the Way Out](https://decomp-academy.dev/courses/gba/lesson/gba-types-narrow-return) — narrow-types, return-values, constants - [Everything Becomes an int](https://decomp-academy.dev/courses/gba/lesson/gba-types-promotion) — narrow-types, promotion, stores - [Casts You Can See](https://decomp-academy.dev/courses/gba/lesson/gba-types-cast) — narrow-types, casts, shifts - [Same Width, Different Sign](https://decomp-academy.dev/courses/gba/lesson/gba-types-sign-change) — narrow-types, casts, loads - [Comparing Narrow Values](https://decomp-academy.dev/courses/gba/lesson/gba-types-narrow-compare) — narrow-types, comparisons, branches - [An s16 That Keeps Truncating](https://decomp-academy.dev/courses/gba/lesson/gba-types-narrow-accumulator) — narrow-types, loops, promotion - [Mixing Widths](https://decomp-academy.dev/courses/gba/lesson/gba-types-mixed) — narrow-types, promotion, comparisons - [Capstone: Widths and Signs](https://decomp-academy.dev/courses/gba/lesson/gba-types-capstone) — narrow-types, promotion, stores ##### Pointers and Addressing — Tiny offsets, register offsets, and walking memory. - [Reading Through a Pointer](https://decomp-academy.dev/courses/gba/lesson/gba-memory-deref) — pointers, loads, addressing - [Writing Through a Pointer](https://decomp-academy.dev/courses/gba/lesson/gba-memory-store) — pointers, stores, void-returns - [A Constant Index Is an Offset](https://decomp-academy.dev/courses/gba/lesson/gba-memory-const-index) — pointers, arrays, addressing - [The Offset Ceiling](https://decomp-academy.dev/courses/gba/lesson/gba-memory-offset-limit) — addressing, arrays, encoding-limits - [A Variable Index](https://decomp-academy.dev/courses/gba/lesson/gba-memory-var-index) — pointers, arrays, addressing - [Byte Arrays Need No Scaling](https://decomp-academy.dev/courses/gba/lesson/gba-memory-byte-array) — pointers, arrays, narrow-types - [Halfword Arrays](https://decomp-academy.dev/courses/gba/lesson/gba-memory-halfword-array) — pointers, arrays, addressing - [Pointer Arithmetic](https://decomp-academy.dev/courses/gba/lesson/gba-memory-pointer-arithmetic) — pointers, addressing, strength-reduction - [Subtracting Pointers](https://decomp-academy.dev/courses/gba/lesson/gba-memory-difference) — pointers, addressing, strength-reduction - [Checking for NULL](https://decomp-academy.dev/courses/gba/lesson/gba-memory-null-check) — pointers, branches, control-flow - [Swapping Two Slots](https://decomp-academy.dev/courses/gba/lesson/gba-memory-swap) — pointers, loads, stores - [Reading From Two Arrays](https://decomp-academy.dev/courses/gba/lesson/gba-memory-two-arrays) — pointers, arrays, register-allocation - [Storing at a Computed Index](https://decomp-academy.dev/courses/gba/lesson/gba-memory-write-index) — pointers, arrays, stores - [A Two-Dimensional Index](https://decomp-academy.dev/courses/gba/lesson/gba-memory-grid) — pointers, arrays, strength-reduction - [Calling Through a Pointer](https://decomp-academy.dev/courses/gba/lesson/gba-memory-function-pointer) — function-pointers, calling-convention, interworking - [Capstone: A Lookup Table](https://decomp-academy.dev/courses/gba/lesson/gba-memory-capstone) — pointers, arrays, branches, narrow-types ##### Structs — Fields, padding, bitfields and the offsets that outgrow the instruction. - [A Field Is an Offset](https://decomp-academy.dev/courses/gba/lesson/gba-structs-read-field) — structs, memory, offsets - [Writing a Field](https://decomp-academy.dev/courses/gba/lesson/gba-structs-write-field) — structs, memory, stores - [Narrow Fields](https://decomp-academy.dev/courses/gba/lesson/gba-structs-narrow-field) — structs, types, loads - [Reading the Padding](https://decomp-academy.dev/courses/gba/lesson/gba-structs-padding) — structs, alignment, offsets - [A Field Past the Ceiling](https://decomp-academy.dev/courses/gba/lesson/gba-structs-far-field) — structs, addressing, offsets - [Nested Structs](https://decomp-academy.dev/courses/gba/lesson/gba-structs-nested) — structs, offsets, stores - [An Array of Structs](https://decomp-academy.dev/courses/gba/lesson/gba-structs-array-index) — structs, arrays, shifts - [A Size That Is Not a Power of Two](https://decomp-academy.dev/courses/gba/lesson/gba-structs-odd-size) — structs, arrays, strength-reduction - [An Array Inside a Struct](https://decomp-academy.dev/courses/gba/lesson/gba-structs-array-field) — structs, arrays, addressing - [Unions](https://decomp-academy.dev/courses/gba/lesson/gba-structs-union) — structs, unions, types - [Reading a Bitfield](https://decomp-academy.dev/courses/gba/lesson/gba-structs-bitfield-read) — structs, bitfields, shifts - [Writing a Bitfield](https://decomp-academy.dev/courses/gba/lesson/gba-structs-bitfield-write) — structs, bitfields, masking - [Flag Bits in a Field](https://decomp-academy.dev/courses/gba/lesson/gba-structs-flags) — structs, bitwise, types - [Chasing a next Pointer](https://decomp-academy.dev/courses/gba/lesson/gba-structs-linked-list) — structs, loops, pointers - [Copying a Struct](https://decomp-academy.dev/courses/gba/lesson/gba-structs-copy) — structs, memory, arrays - [Capstone: An Entity Update](https://decomp-academy.dev/courses/gba/lesson/gba-structs-capstone) — structs, bitwise, control-flow ##### Floats Without an FPU — Why every float is a function call, and what real GBA code does instead. - [The Chip Cannot Do Decimals](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-no-fpu) — floating-point, soft-float, fixed-point - [Adding Two Floats](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-float-add) — floating-point, soft-float, calling-convention - [Multiplying Floats](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-float-multiply) — floating-point, soft-float, memory - [Dividing Floats](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-float-divide) — floating-point, soft-float, strength-reduction - [Converting In](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-int-to-float) — floating-point, conversions, soft-float - [Converting Out](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-float-to-int) — floating-point, conversions, soft-float - [Comparing Floats](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-float-compare) — floating-point, comparison, control-flow - [A Float Constant in the Pool](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-float-constant) — floating-point, literal-pool, constants - [Doubles Cost Double](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-double) — floating-point, doubles, literal-pool - [A Chain of Calls](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-float-chain) — floating-point, soft-float, register-allocation - [The Fixed-Point Answer](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-fixed-intro) — fixed-point, shifts, constants - [A Fixed-Point Multiply](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-fixed-multiply) — fixed-point, arithmetic, shifts - [Rounding a Fixed-Point Result](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-fixed-rounding) — fixed-point, rounding, signed-shift - [Dividing in Fixed Point](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-fixed-divide) — fixed-point, division, rounding - [Interpolating](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-fixed-lerp) — fixed-point, arithmetic, shifts - [Capstone: Fixed-Point Motion](https://decomp-academy.dev/courses/gba/lesson/gba-numbers-capstone) — fixed-point, rounding, control-flow ##### Tier Finale — Five functions that need everything the tier taught at once. - [Masked, Guarded, Summed](https://decomp-academy.dev/courses/gba/lesson/gba-finale-masked-sum) — loops, bitwise, control-flow - [Packing From a Table](https://decomp-academy.dev/courses/gba/lesson/gba-finale-packed-table) — bitwise, memory, constants - [Divide, Then Clamp](https://decomp-academy.dev/courses/gba/lesson/gba-finale-divide-clamp) — division, control-flow, calling-convention - [Scanning Structs](https://decomp-academy.dev/courses/gba/lesson/gba-finale-struct-scan) — structs, loops, narrow-types - [Capstone: Fixed-Point Accumulate](https://decomp-academy.dev/courses/gba/lesson/gba-finale-fixed-accumulate) — fixed-point, structs, loops #### The Real Machine — Frames, globals, hardware and the optimizer ##### Frames and Calls — push, pop, callee-saved registers and the interworking return. - [A Function With No Frame](https://decomp-academy.dev/courses/gba/lesson/gba-abi-leaf) — abi, calling-convention, registers - [Saving the Return Address](https://decomp-academy.dev/courses/gba/lesson/gba-abi-push-lr) — abi, calls, epilogue - [Registers That Must Survive](https://decomp-academy.dev/courses/gba/lesson/gba-abi-callee-saved) — abi, callee-saved, calls - [Four Arguments Fit](https://decomp-academy.dev/courses/gba/lesson/gba-abi-four-args) — abi, arguments, calls - [The Fifth Argument](https://decomp-academy.dev/courses/gba/lesson/gba-abi-fifth-arg) — abi, arguments, stack - [Pushing Arguments for a Call](https://decomp-academy.dev/courses/gba/lesson/gba-abi-caller-stack-args) — abi, arguments, stack - [Keeping a Value Across a Call](https://decomp-academy.dev/courses/gba/lesson/gba-abi-keep-across-call) — abi, callee-saved, calls - [Two Calls in a Row](https://decomp-academy.dev/courses/gba/lesson/gba-abi-two-calls) — abi, callee-saved, calls - [Feeding One Call Into Another](https://decomp-academy.dev/courses/gba/lesson/gba-abi-nested-result) — abi, calls, arguments - [Room on the Stack](https://decomp-academy.dev/courses/gba/lesson/gba-abi-local-array) — abi, frames, stack - [The Address of a Local](https://decomp-academy.dev/courses/gba/lesson/gba-abi-address-of-local) — abi, frames, pointers - [Running Out of Registers](https://decomp-academy.dev/courses/gba/lesson/gba-abi-spill) — abi, callee-saved, register-pressure - [Narrow Arguments at a Call Boundary](https://decomp-academy.dev/courses/gba/lesson/gba-abi-narrow-args) — abi, narrow-types, calls - [Capstone: A Frame That Earns It](https://decomp-academy.dev/courses/gba/lesson/gba-abi-capstone) — abi, frames, loops ##### Globals and the Literal Pool — Every global address is a word parked inside the function. - [Reading a Global](https://decomp-academy.dev/courses/gba/lesson/gba-globals-read) — globals, literal-pool, memory - [Writing a Global](https://decomp-academy.dev/courses/gba/lesson/gba-globals-write) — globals, literal-pool, memory - [Reading the Pool](https://decomp-academy.dev/courses/gba/lesson/gba-globals-pool-anatomy) — literal-pool, globals, constants - [Two Globals, Two Words](https://decomp-academy.dev/courses/gba/lesson/gba-globals-two) — globals, literal-pool, operand-order - [Read, Modify, Write](https://decomp-academy.dev/courses/gba/lesson/gba-globals-rmw) — globals, literal-pool, memory - [A Global Array, Constant Index](https://decomp-academy.dev/courses/gba/lesson/gba-globals-array-const) — globals, arrays, addressing - [A Global Array, Variable Index](https://decomp-academy.dev/courses/gba/lesson/gba-globals-array-var) — globals, arrays, addressing - [Narrow Globals](https://decomp-academy.dev/courses/gba/lesson/gba-globals-narrow) — globals, narrow-types, sign-extension - [Statics Look the Same](https://decomp-academy.dev/courses/gba/lesson/gba-globals-static) — globals, statics, literal-pool - [Taking the Address](https://decomp-academy.dev/courses/gba/lesson/gba-globals-address-of) — globals, pointers, literal-pool - [A Global Inside a Loop](https://decomp-academy.dev/courses/gba/lesson/gba-globals-in-loop) — globals, loops, registers - [A Global Struct](https://decomp-academy.dev/courses/gba/lesson/gba-globals-struct) — globals, structs, addressing - [A Constant Table](https://decomp-academy.dev/courses/gba/lesson/gba-globals-const-table) — globals, constants, arrays - [Capstone: Global State](https://decomp-academy.dev/courses/gba/lesson/gba-globals-capstone) — globals, literal-pool, branches ##### Hardware Registers — volatile, memory-mapped IO, and the code the GBA's hardware forces. - [The GBA's Memory Map](https://decomp-academy.dev/courses/gba/lesson/gba-hardware-memory-map) — memory-map, hardware, volatile, literal-pool - [Reading a Hardware Register](https://decomp-academy.dev/courses/gba/lesson/gba-hardware-read-register) — hardware, volatile, literal-pool - [Writing a Hardware Register](https://decomp-academy.dev/courses/gba/lesson/gba-hardware-write-register) — hardware, constants, literal-pool - [The Load That Cannot Be Reused](https://decomp-academy.dev/courses/gba/lesson/gba-hardware-volatile-vs-not) — volatile, hardware, optimizer - [Read, Modify, Write a Register](https://decomp-academy.dev/courses/gba/lesson/gba-hardware-rmw) — hardware, bitwise, constants - [Clearing Control Bits](https://decomp-academy.dev/courses/gba/lesson/gba-hardware-clear-bits) — hardware, bitwise, constants - [Waiting on the Hardware](https://decomp-academy.dev/courses/gba/lesson/gba-hardware-poll) — volatile, loops, hardware - [Packing Two Edges Into One Register](https://decomp-academy.dev/courses/gba/lesson/gba-hardware-packed-write) — hardware, narrow-types, shifts - [Writing a Palette Entry](https://decomp-academy.dev/courses/gba/lesson/gba-hardware-palette) — hardware, palette, addressing - [VRAM Will Not Take a Byte](https://decomp-academy.dev/courses/gba/lesson/gba-hardware-vram-halfword) — hardware, vram, bitwise - [Updating a Sprite](https://decomp-academy.dev/courses/gba/lesson/gba-hardware-sprite) — hardware, structs, volatile - [Capstone: A Scanline Effect](https://decomp-academy.dev/courses/gba/lesson/gba-hardware-capstone) — hardware, branches, shifts ##### 64-bit Values — Two registers pretending to be one number. - [A Number in Two Registers](https://decomp-academy.dev/courses/gba/lesson/gba-int64-pairs) — int64, registers, memory - [Carrying Between Halves](https://decomp-academy.dev/courses/gba/lesson/gba-int64-add) — int64, arithmetic, globals - [Borrowing](https://decomp-academy.dev/courses/gba/lesson/gba-int64-subtract) — int64, arithmetic, memory - [Shifting Across the Seam](https://decomp-academy.dev/courses/gba/lesson/gba-int64-shift) — int64, shifts, memory - [Widening to 64 Bits](https://decomp-academy.dev/courses/gba/lesson/gba-int64-widen) — int64, types, memory - [Throwing the High Half Away](https://decomp-academy.dev/courses/gba/lesson/gba-int64-truncate) — int64, types, calls - [Comparing 64-bit Values](https://decomp-academy.dev/courses/gba/lesson/gba-int64-compare) — int64, branches, memory - [A 64-bit Multiply Is a Call](https://decomp-academy.dev/courses/gba/lesson/gba-int64-multiply) — int64, libgcc, globals - [No Gap in the Argument Registers](https://decomp-academy.dev/courses/gba/lesson/gba-int64-argument-packing) — int64, abi, arguments - [Capstone: A 64-bit Accumulator](https://decomp-academy.dev/courses/gba/lesson/gba-int64-capstone) — int64, loops, libgcc ##### What gcc 2.9 Does To Your Code — The transformations you have to write around, not against. - [The Second Time Is Free](https://decomp-academy.dev/courses/gba/lesson/gba-optimizer-cse) — optimizer, common-subexpression, pointers - [Lifted Out of the Loop](https://decomp-academy.dev/courses/gba/lesson/gba-optimizer-hoisting) — optimizer, loops, globals - [Sums Rearranged](https://decomp-academy.dev/courses/gba/lesson/gba-optimizer-reassociation) — optimizer, arithmetic, constants - [Code That Left No Trace](https://decomp-academy.dev/courses/gba/lesson/gba-optimizer-dead-code) — optimizer, dead-code, calls - [Multiplication Turned Into Addition](https://decomp-academy.dev/courses/gba/lesson/gba-optimizer-strength-reduction) — optimizer, loops, induction-variables - [The Order You Declare Them](https://decomp-academy.dev/courses/gba/lesson/gba-optimizer-declaration-order) — optimizer, registers, calls - [Helpers That Leave No Trace](https://decomp-academy.dev/courses/gba/lesson/gba-optimizer-inline) — optimizer, inlining, loops - [Two Paths, One Ending](https://decomp-academy.dev/courses/gba/lesson/gba-optimizer-tail-merge) — optimizer, branches, calls - [Which Side Falls Through](https://decomp-academy.dev/courses/gba/lesson/gba-optimizer-branch-shape) — optimizer, branches, control-flow - [Arithmetic Done at Compile Time](https://decomp-academy.dev/courses/gba/lesson/gba-optimizer-constant-folding) — optimizer, constants, literal-pool - [One Pool Word, Several Uses](https://decomp-academy.dev/courses/gba/lesson/gba-optimizer-shared-pool) — optimizer, literal-pool, globals - [Capstone: Writing For the Optimizer](https://decomp-academy.dev/courses/gba/lesson/gba-optimizer-capstone) — optimizer, loops, globals ##### Tier Finale — Frames, globals, hardware and 64-bit values, fused. - [A Global Across a Call](https://decomp-academy.dev/courses/gba/lesson/gba-realfinale-global-call) — globals, literal-pool, calls - [Hardware in a Loop](https://decomp-academy.dev/courses/gba/lesson/gba-realfinale-hardware-loop) — volatile, loops, globals - [Fixed Point in a Frame](https://decomp-academy.dev/courses/gba/lesson/gba-realfinale-frame-fixed) — fixed-point, calls, frames - [A 64-bit Global](https://decomp-academy.dev/courses/gba/lesson/gba-realfinale-int64-global) — int64, globals, carry - [Grand Capstone: The Frame Update](https://decomp-academy.dev/courses/gba/lesson/gba-realfinale-grand) — capstone, structs, fixed-point, volatile #### Proving Ground — Real Game Boy Advance functions, start to finish ##### Real-World Mastery — Authentic GBA game code — fixed-point math, hardware effects and the routines every cartridge has. - [MultiplyQ4: Fixed-Point Rounding](https://decomp-academy.dev/courses/gba/lesson/gba-idioms-multiply-q4) — fixed-point, arithmetic, rounding - [UpdateWindowCircleEffect: A Hardware Window](https://decomp-academy.dev/courses/gba/lesson/gba-idioms-window-circle) — hardware-registers, fixed-point, bios - [Positioning a Sprite](https://decomp-academy.dev/courses/gba/lesson/gba-mastery-oam-set) — hardware-registers, bitfields, structs - [Fading a Palette](https://decomp-academy.dev/courses/gba/lesson/gba-mastery-palette-fade) — bitfields, fixed-point, narrow-types - [Filling a Tilemap Rectangle](https://decomp-academy.dev/courses/gba/lesson/gba-mastery-tilemap-fill) — loops, pointers, strength-reduction - [The Random Number Generator](https://decomp-academy.dev/courses/gba/lesson/gba-mastery-rng) — globals, literal-pool, arithmetic - [A Save-File Checksum](https://decomp-academy.dev/courses/gba/lesson/gba-mastery-checksum) — loops, masks, narrow-types - [Detecting a Button Press](https://decomp-academy.dev/courses/gba/lesson/gba-mastery-input-edge) — hardware-registers, bitwise, globals - [Integrating Velocity](https://decomp-academy.dev/courses/gba/lesson/gba-mastery-velocity) — structs, fixed-point, narrow-types - [A Box Overlap Test](https://decomp-academy.dev/courses/gba/lesson/gba-mastery-collision) — branches, structs, boolean-logic - [Advancing an Animation](https://decomp-academy.dev/courses/gba/lesson/gba-mastery-animate) — narrow-types, structs, globals - [Following the Player](https://decomp-academy.dev/courses/gba/lesson/gba-mastery-camera) — division, structs, branches - [Kicking Off a DMA](https://decomp-academy.dev/courses/gba/lesson/gba-mastery-dma-copy) — hardware-registers, literal-pool, constants - [Grand Capstone: The Entity Sweep](https://decomp-academy.dev/courses/gba/lesson/gba-mastery-entity-sweep) — loops, structs, narrow-types, bitwise ### Nintendo 64 — Decompile Nintendo 64 MIPS assembly back into byte-matching C, graded live by the real SGI IDO 5.3 compiler that shipped N64 games. #### Warm-up — Learn to read the MIPS machine ##### Foundations — What decompilation is, MIPS registers, delay slots, and reading IDO output. - [What Matching Decompilation Is](https://decomp-academy.dev/courses/n64-c/lesson/foundations-what-is-matching) — matching, toolchain, workflow, mental-model - [How to Read MIPS Assembly](https://decomp-academy.dev/courses/n64-c/lesson/foundations-reading-assembly) — assembly, registers, delay-slots, mental-model - [Your First Match](https://decomp-academy.dev/courses/n64-c/lesson/foundations-welcome) — registers, return-value, workflow - [Arguments Arrive in a0](https://decomp-academy.dev/courses/n64-c/lesson/foundations-identity) — registers, calling-convention - [Immediates: Math With Constants](https://decomp-academy.dev/courses/n64-c/lesson/foundations-immediate) — arithmetic, immediates - [Subtracting a Constant](https://decomp-academy.dev/courses/n64-c/lesson/foundations-subtract-const) — arithmetic, immediates - [Multiply Without a Multiplier](https://decomp-academy.dev/courses/n64-c/lesson/foundations-mul-const) — arithmetic, strength-reduction, shifts - [Dividing by a Constant](https://decomp-academy.dev/courses/n64-c/lesson/foundations-div-const) — arithmetic, divide, hi-lo - [Negation and the Zero Register](https://decomp-academy.dev/courses/n64-c/lesson/foundations-negate) — arithmetic, registers, pseudo-ops ##### Reading Signatures — No more starter functions — derive the arguments and return type yourself. - [The Band-Aid Comes Off](https://decomp-academy.dev/courses/n64-c/lesson/signatures-bandaid) — calling-convention, workflow, mental-model - [Counting the Arguments](https://decomp-academy.dev/courses/n64-c/lesson/signatures-counting-args) — calling-convention, registers, arguments - [Read an Argument Off the Registers](https://decomp-academy.dev/courses/n64-c/lesson/signatures-arg-registers) — calling-convention, registers, arguments - [Count Them Yourself](https://decomp-academy.dev/courses/n64-c/lesson/signatures-derive) — calling-convention, arguments, arithmetic #### Core idioms — Every shape C compiles into ##### Integer Arithmetic — Register math, shift chains for constants, HI/LO, and the divide fix-ups IDO can't help emitting. - [On to Arithmetic](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-intro) — arithmetic, mental-model - [Adding Two Registers](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-add-registers) — arithmetic, registers - [Subtraction and Operand Order](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-sub-registers) — arithmetic, registers - [Chains of Adds and Subtracts](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-add-sub-chain) — arithmetic, registers - [Mixing Registers and Constants](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-chain-immediate) — arithmetic, immediates - [Shift Chains: The Add Form](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-mul-add-form) — arithmetic, strength-reduction, shifts - [Shift Chains: The Subtract Form](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-mul-sub-form) — arithmetic, strength-reduction, shifts - [Chains That Keep Going](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-mul-longer-chain) — arithmetic, strength-reduction, shifts - [The Compiler Never Gives Up](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-mul-hundred) — arithmetic, strength-reduction, fingerprints - [Scale One, Add the Other](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-scale-add) — arithmetic, shifts, registers - [The Real Multiplier at Last](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-variable-multiply) — arithmetic, multiply, hi-lo - [mfhi: The Other Half of Division](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-remainder) — arithmetic, divide, hi-lo - [divu: Signedness Shows in the Mnemonic](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-unsigned-divide) — arithmetic, divide, types - [Dividing Unsigned by a Power of Two](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-unsigned-pow2-divide) — arithmetic, divide, shifts - [Remainder by Mask](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-unsigned-pow2-remainder) — arithmetic, divide, bitwise - [Signed Powers of Two Need a Fix-Up](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-signed-pow2-divide) — arithmetic, divide, shifts, delay-slots, fingerprints - [Signed Remainder, Sign Restored](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-signed-pow2-remainder) — arithmetic, divide, bitwise, fingerprints - [lui/ori: Constants Too Big to Ride](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-big-constants) — immediates, registers - [Big Constants in Arithmetic](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-big-const-arithmetic) — immediates, arithmetic, registers - [Quotient, Remainder, and the Safety Net](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-divmod-guards) — arithmetic, divide, hi-lo, fingerprints - [The (-K) - x Fingerprint](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-neg-sum) — arithmetic, fingerprints, registers - [Capstone: Chain Within a Chain](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-capstone-chain) — arithmetic, strength-reduction, shifts, capstone - [Capstone: Product, Wrapped](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-capstone-mul-mod) — arithmetic, multiply, divide, hi-lo, capstone - [Capstone: The Average](https://decomp-academy.dev/courses/n64-c/lesson/arithmetic-capstone-average) — arithmetic, divide, shifts, delay-slots, capstone ##### Bitwise & Shifts — AND, OR, XOR, NOR-as-NOT, the three shifts, and the field-packing tricks built from them. - [andi: Keeping Only Some Bits](https://decomp-academy.dev/courses/n64-c/lesson/bitwise-and-mask) — bitwise, immediates - [ori: Forcing Bits On](https://decomp-academy.dev/courses/n64-c/lesson/bitwise-or-set) — bitwise, immediates - [xori: Flipping Bits](https://decomp-academy.dev/courses/n64-c/lesson/bitwise-xor-toggle) — bitwise, immediates - [Bitwise Between Registers](https://decomp-academy.dev/courses/n64-c/lesson/bitwise-register-forms) — bitwise, registers - [nor: The Instruction Behind ~](https://decomp-academy.dev/courses/n64-c/lesson/bitwise-nor-not) — bitwise, registers, fingerprints - [sll, srl, sra: The Shift Family](https://decomp-academy.dev/courses/n64-c/lesson/bitwise-shift-trio) — shifts, types - [Shifting by a Variable](https://decomp-academy.dev/courses/n64-c/lesson/bitwise-variable-shifts) — shifts, registers, types - [Clearing Bits: AND With a Negative](https://decomp-academy.dev/courses/n64-c/lesson/bitwise-clear-bits) — bitwise, masks, fingerprints - [Testing a Bit](https://decomp-academy.dev/courses/n64-c/lesson/bitwise-bit-test) — bitwise, booleans, fingerprints - [The Sign Bit, Two Ways](https://decomp-academy.dev/courses/n64-c/lesson/bitwise-sign-bit) — bitwise, shifts, types, fingerprints - [Packing Two Values Into One](https://decomp-academy.dev/courses/n64-c/lesson/bitwise-pack-halves) — bitwise, shifts, masks - [Extracting a Field](https://decomp-academy.dev/courses/n64-c/lesson/bitwise-extract-field) — bitwise, shifts, masks - [Replacing a Field](https://decomp-academy.dev/courses/n64-c/lesson/bitwise-insert-field) — bitwise, masks, fingerprints - [Capstone: The Rotate That Isn't There](https://decomp-academy.dev/courses/n64-c/lesson/bitwise-capstone-swap) — bitwise, shifts, capstone ##### Control Flow & Delay Slots — Branches, compares, booleans made of arithmetic — and the delay slot, where IDO hides real work. - [Anatomy of a Branch](https://decomp-academy.dev/courses/n64-c/lesson/control-branch-anatomy) — control-flow, branches, delay-slots, mental-model - [Your First Branch](https://decomp-academy.dev/courses/n64-c/lesson/control-first-if) — control-flow, branches, delay-slots - [Branching on Two Values](https://decomp-academy.dev/courses/n64-c/lesson/control-compare-branch) — control-flow, branches, compare - [Comparing Against a Constant](https://decomp-academy.dev/courses/n64-c/lesson/control-const-compare) — control-flow, branches, immediates, fingerprints - [blez, bgtz, bltz, bgez: Sign Tests](https://decomp-academy.dev/courses/n64-c/lesson/control-zero-family) — control-flow, branches, compare - [slt: A Comparison You Can Hold](https://decomp-academy.dev/courses/n64-c/lesson/control-slt-bool) — compare, booleans - [slti and the xori Flip](https://decomp-academy.dev/courses/n64-c/lesson/control-slti-flip) — compare, booleans, immediates, fingerprints - [Equality as a Value](https://decomp-academy.dev/courses/n64-c/lesson/control-bool-eq) — booleans, compare, fingerprints - [Inequality as a Value](https://decomp-academy.dev/courses/n64-c/lesson/control-bool-ne) — booleans, compare, fingerprints - [sltu: The Compare Chooses the Types](https://decomp-academy.dev/courses/n64-c/lesson/control-unsigned-compare) — compare, types, booleans - [Branch Likely: The Slot That Doesn't Always Run](https://decomp-academy.dev/courses/n64-c/lesson/control-likely-branch) — branches, branch-likely, delay-slots, fingerprints - [Three Ways Out](https://decomp-academy.dev/courses/n64-c/lesson/control-multi-return) — control-flow, branches, delay-slots - [The Ternary Diamond](https://decomp-academy.dev/courses/n64-c/lesson/control-ternary) — control-flow, branches, fingerprints - [Min and Max](https://decomp-academy.dev/courses/n64-c/lesson/control-min-max) — control-flow, compare, branches - [Absolute Value](https://decomp-academy.dev/courses/n64-c/lesson/control-abs) — control-flow, branches, fingerprints - [Clamping a Value](https://decomp-academy.dev/courses/n64-c/lesson/control-clamp) — control-flow, branches, delay-slots, compare - [&&: A Ladder of Bailouts](https://decomp-academy.dev/courses/n64-c/lesson/control-and-chain) — control-flow, branches, short-circuit, delay-slots - [||: The Ladder Flips](https://decomp-academy.dev/courses/n64-c/lesson/control-or-chain) — control-flow, branches, short-circuit, delay-slots - [A Small switch](https://decomp-academy.dev/courses/n64-c/lesson/control-switch) — control-flow, branches, switch, fingerprints - [Capstone: Step Toward](https://decomp-academy.dev/courses/n64-c/lesson/control-capstone-step) — control-flow, branches, delay-slots, capstone ##### Loops — Rotated bodies, back-edges riding delay slots, and the ×4 unroll — how IDO turns three lines of C into a page of assembly. - [The Anatomy of an IDO Loop](https://decomp-academy.dev/courses/n64-c/lesson/loops-anatomy) — loops, delay-slots, branch-likely, mental-model - [Your First do/while](https://decomp-academy.dev/courses/n64-c/lesson/loops-first-do-while) — loops, do-while, delay-slots - [Counting Up: slt Joins the Loop](https://decomp-academy.dev/courses/n64-c/lesson/loops-counting-up) — loops, do-while, slt, delay-slots - [The Cloned Slot: bnezl Back-Edges](https://decomp-academy.dev/courses/n64-c/lesson/loops-cloned-slot) — loops, branch-likely, delay-slots, fingerprints - [while Means Guard](https://decomp-academy.dev/courses/n64-c/lesson/loops-while-guard) — loops, while, branch-likely, delay-slots - [Looping While Bits Remain](https://decomp-academy.dev/courses/n64-c/lesson/loops-while-nonzero) — loops, while, shifts, delay-slots - [Walking Memory Until Zero](https://decomp-academy.dev/courses/n64-c/lesson/loops-walk-until-zero) — loops, pointers, branch-likely, delay-slots - [The ×4 Unroll (and Its Useless sll)](https://decomp-academy.dev/courses/n64-c/lesson/loops-unroll-fingerprint) — loops, unrolling, fingerprints, arrays - [Unrolled Loads: Reading the Shuffle](https://decomp-academy.dev/courses/n64-c/lesson/loops-unroll-loads) — loops, unrolling, arrays, scheduling - [Fixed Counts: The Unroll With No Remainder](https://decomp-academy.dev/courses/n64-c/lesson/loops-exact-count) — loops, unrolling, arrays, fingerprints - [Two Pointers, One Loop](https://decomp-academy.dev/courses/n64-c/lesson/loops-span) — loops, pointers, unrolling - [Search Loops: A Return in the Middle](https://decomp-academy.dev/courses/n64-c/lesson/loops-sentinel-search) — loops, control-flow, pointers, delay-slots - [Capstone: The Big Scan](https://decomp-academy.dev/courses/n64-c/lesson/loops-capstone-scan) — loops, unrolling, control-flow, capstone ##### Types & Width — Byte and halfword loads as type oracles, the truncation masks and shift pairs, and the homing ritual IDO performs for every narrow argument. - [lb: One Byte, Sign and All](https://decomp-academy.dev/courses/n64-c/lesson/types-load-signed-byte) — types, loads, sign-extension - [lbu: The Zero-Extended Twin](https://decomp-academy.dev/courses/n64-c/lesson/types-load-unsigned-byte) — types, loads, zero-extension - [lh and lhu: Halfwords](https://decomp-academy.dev/courses/n64-c/lesson/types-halfwords) — types, loads, sign-extension, zero-extension - [sb and sh: Stores Don't Care About Sign](https://decomp-academy.dev/courses/n64-c/lesson/types-narrow-stores) — types, stores - [Casting Down, Unsigned: andi](https://decomp-academy.dev/courses/n64-c/lesson/types-unsigned-trunc) — types, casts, bitwise - [Casting Down, Signed: The Shift Pair](https://decomp-academy.dev/courses/n64-c/lesson/types-signed-trunc) — types, casts, shifts, sign-extension - [The Homing Ritual](https://decomp-academy.dev/courses/n64-c/lesson/types-homing-ritual) — types, arg-homing, fingerprints, sign-extension - [Narrow In, Narrow Out](https://decomp-academy.dev/courses/n64-c/lesson/types-narrow-in-out) — types, arg-homing, casts - [Widening Copies: The Load Converts](https://decomp-academy.dev/courses/n64-c/lesson/types-widening-copy) — types, loads, stores - [Narrowing Copies: The Store Converts](https://decomp-academy.dev/courses/n64-c/lesson/types-narrowing-copy) — types, loads, stores - [Comparing Bytes](https://decomp-academy.dev/courses/n64-c/lesson/types-narrow-compare) — types, booleans, comparisons - [Bytes in a Loop](https://decomp-academy.dev/courses/n64-c/lesson/types-byte-loop) — types, loops, pointers, delay-slots - [Packing Bytes Into Memory](https://decomp-academy.dev/courses/n64-c/lesson/types-pack-bytes) — types, stores, arrays - [Capstone: Three Widths, One Expression](https://decomp-academy.dev/courses/n64-c/lesson/types-capstone-mixed) — types, loads, shifts, capstone ##### Pointers & Memory — offset(base) addressing, the sll/addu indexing trio, strides by width, NULL guards, and the pointer arithmetic that hides a divide. - [sw: Writing Through a Pointer](https://decomp-academy.dev/courses/n64-c/lesson/pointers-store-word) — pointers, stores - [Constant Indexes Live in the Offset](https://decomp-academy.dev/courses/n64-c/lesson/pointers-const-index) — pointers, arrays, offsets - [The Indexing Trio: sll, addu, lw](https://decomp-academy.dev/courses/n64-c/lesson/pointers-var-index) — pointers, arrays, indexing, shifts - [Indexed Stores](https://decomp-academy.dev/courses/n64-c/lesson/pointers-index-store) — pointers, arrays, stores - [Neighbors: The Offset Comes Back](https://decomp-academy.dev/courses/n64-c/lesson/pointers-neighbors) — pointers, arrays, offsets, cse - [Halfword Arrays: Stride 2](https://decomp-academy.dev/courses/n64-c/lesson/pointers-halfword-stride) — pointers, arrays, types, shifts - [Byte Arrays: No Shift at All](https://decomp-academy.dev/courses/n64-c/lesson/pointers-byte-stride) — pointers, arrays, types - [Two Arrays, One Index](https://decomp-academy.dev/courses/n64-c/lesson/pointers-two-arrays) — pointers, arrays, cse - [Read, Modify, Write](https://decomp-academy.dev/courses/n64-c/lesson/pointers-rmw) — pointers, stores, rmw - [Subtracting Pointers Hides a Divide](https://decomp-academy.dev/courses/n64-c/lesson/pointers-diff) — pointers, arithmetic, shifts - [The NULL Guard](https://decomp-academy.dev/courses/n64-c/lesson/pointers-null-check) — pointers, , branches - [The Swap](https://decomp-academy.dev/courses/n64-c/lesson/pointers-swap) — pointers, stores, scheduling - [Post-Increment Becomes Offsets](https://decomp-academy.dev/courses/n64-c/lesson/pointers-advance) — pointers, stores, offsets - [Two Dimensions, Two Shifts](https://decomp-academy.dev/courses/n64-c/lesson/pointers-grid) — pointers, arrays, indexing, shifts - [Capstone: The Guarded Update](https://decomp-academy.dev/courses/n64-c/lesson/pointers-capstone-table) — pointers, , rmw, capstone ##### Structs, Unions & Bitfields — Field offsets and padding, arrays of structs and their sizeof multiplies, unions that alias, bitfield slice sequences, and flag bytes updated in place. - [Fields Are Offsets](https://decomp-academy.dev/courses/n64-c/lesson/structs-first-field) — structs, offsets - [Filling In Fields](https://decomp-academy.dev/courses/n64-c/lesson/structs-field-store) — structs, stores - [Narrow Fields and the Gaps Between](https://decomp-academy.dev/courses/n64-c/lesson/structs-mixed-widths) — structs, types, alignment - [Storing Into Narrow Fields](https://decomp-academy.dev/courses/n64-c/lesson/structs-narrow-store) — structs, stores, types - [Updating a Field in Place](https://decomp-academy.dev/courses/n64-c/lesson/structs-field-rmw) — structs, rmw, shifts - [Structs Inside Structs](https://decomp-academy.dev/courses/n64-c/lesson/structs-nested) — structs, offsets, nesting - [Arrays of Structs: The sizeof Multiply](https://decomp-academy.dev/courses/n64-c/lesson/structs-struct-array) — structs, arrays, strength-reduction - [A Constant Element Folds Away](https://decomp-academy.dev/courses/n64-c/lesson/structs-const-element) — structs, arrays, offsets, rmw - [An Array Inside a Struct](https://decomp-academy.dev/courses/n64-c/lesson/structs-array-field) — structs, arrays, indexing - [Unions: One Offset, Many Readings](https://decomp-academy.dev/courses/n64-c/lesson/structs-union) — unions, types, endianness - [Bitfields: Reading a Slice](https://decomp-academy.dev/courses/n64-c/lesson/structs-bitfield-read) — bitfields, shifts, sign-extension - [Bitfields: Writing a Slice](https://decomp-academy.dev/courses/n64-c/lesson/structs-bitfield-write) — bitfields, masks, rmw - [Setting a Flag](https://decomp-academy.dev/courses/n64-c/lesson/structs-flag-set) — structs, flags, rmw - [Clearing and Testing Flags](https://decomp-academy.dev/courses/n64-c/lesson/structs-flag-clear-test) — structs, flags, booleans - [Chasing next](https://decomp-academy.dev/courses/n64-c/lesson/structs-next-chase) — structs, pointers, loops, branch-likely - [Calling Through a Field](https://decomp-academy.dev/courses/n64-c/lesson/structs-fnptr-call) — structs, function-pointers, jalr - [Copying a Struct Whole](https://decomp-academy.dev/courses/n64-c/lesson/structs-copy) — structs, copies, fingerprints - [Capstone: Damage Control](https://decomp-academy.dev/courses/n64-c/lesson/structs-capstone-damage) — structs, flags, rmw, control-flow, capstone ##### Floating Point (COP1) — The FPU's own registers and grammar — .s and .d arithmetic, the two ways constants materialize, border crossings between int and float, three-beat compares, and the hazard nops that pad it all. - [Welcome to the FPU](https://decomp-academy.dev/courses/n64-c/lesson/floats-fpu-hello) — floats, fpu, abi - [Chains, ft0, and the mul.s nop](https://decomp-academy.dev/courses/n64-c/lesson/floats-fpu-chains) — floats, fpu, expression-chains - [lwc1 and swc1: Floats in Memory](https://decomp-academy.dev/courses/n64-c/lesson/floats-memory) — floats, loads, stores, pointers - [Float Constants I: A lui With Clean Bits](https://decomp-academy.dev/courses/n64-c/lesson/floats-clean-constants) — floats, constants, mtc1, hazards - [Float Constants II: Loaded From .rodata](https://decomp-academy.dev/courses/n64-c/lesson/floats-rodata-constants) — floats, constants, rodata, hi-lo - [Crossing the Border: int to float](https://decomp-academy.dev/courses/n64-c/lesson/floats-int-to-float) — floats, conversion, mtc1, hazards - [Crossing Back: trunc.w.s and mfc1](https://decomp-academy.dev/courses/n64-c/lesson/floats-float-to-int) — floats, conversion, trunc, mfc1 - [In, Compute, Out: The Round Trip](https://decomp-academy.dev/courses/n64-c/lesson/floats-round-trip) — floats, conversion, constants - [c.lt.s: The Three-Beat Compare](https://decomp-academy.dev/courses/n64-c/lesson/floats-compare-basics) — floats, compares, bc1f, booleans - [There Is No c.gt.s](https://decomp-academy.dev/courses/n64-c/lesson/floats-swapped-operands) — floats, compares, fingerprints - [c.le.s and the Mirrored >=](https://decomp-academy.dev/courses/n64-c/lesson/floats-le-ge) — floats, compares, fingerprints - [c.eq.s, and != in the Branch](https://decomp-academy.dev/courses/n64-c/lesson/floats-eq-ne) — floats, compares, bc1t, fingerprints - [Min and Max: bc1fl and mov.s](https://decomp-academy.dev/courses/n64-c/lesson/floats-min-max) — floats, compares, branch-likely, min-max - [Clamp: Two Guards, One Constant Carrier](https://decomp-academy.dev/courses/n64-c/lesson/floats-clamp) — floats, compares, clamp, constants - [Weighted Mixes and Midpoints](https://decomp-academy.dev/courses/n64-c/lesson/floats-mixes) — floats, constants, expression-chains - [neg.s: Flipping the Sign](https://decomp-academy.dev/courses/n64-c/lesson/floats-negate) — floats, negation - [Doubles: .d and Register Pairs](https://decomp-academy.dev/courses/n64-c/lesson/floats-doubles) — floats, doubles, fpu - [Double Constants: Two Ferries or One ldc1](https://decomp-academy.dev/courses/n64-c/lesson/floats-double-constants) — floats, doubles, constants - [The Missing f: A Double Detour](https://decomp-academy.dev/courses/n64-c/lesson/floats-missing-f) — floats, doubles, conversion, fingerprints - [Floats in Structs: The Vec Pattern](https://decomp-academy.dev/courses/n64-c/lesson/floats-vec-structs) — floats, structs, pointers - [Capstone: Approach](https://decomp-academy.dev/courses/n64-c/lesson/floats-capstone-approach) — floats, compares, clamp, constants, capstone ##### Putting It Together — Whole small functions with nothing new in them — arithmetic, bits, branches, loops, widths, pointers, and structs fused into realistic leaf bodies, read end to end. - [A Hash in a Walk](https://decomp-academy.dev/courses/n64-c/lesson/finale-hash-walk) — loops, pointers, types, multiplication, capstone - [A Timer Ticks Down](https://decomp-academy.dev/courses/n64-c/lesson/finale-timer-tick) — structs, control-flow, types, capstone - [Four Bytes, One Word](https://decomp-academy.dev/courses/n64-c/lesson/finale-pack-color) — bitwise, pointers, types, capstone - [Searching a Table](https://decomp-academy.dev/courses/n64-c/lesson/finale-table-search) — structs, loops, pointers, multi-return, capstone - [Grand Capstone: The Entity Sweep](https://decomp-academy.dev/courses/n64-c/lesson/finale-entity-sweep) — loops, unrolling, structs, flags, types, capstone #### The real ABI — Frames, globals, the optimizer, 64-bit ##### Functions & the o32 ABI — Argument registers, stack args, frames, the jal delay slot, homing, and saved registers. - [Four Arguments, Four Registers](https://decomp-academy.dev/courses/n64-c/lesson/abi-four-args) — abi, arguments, arithmetic - [The Fifth Argument Lives on the Stack](https://decomp-academy.dev/courses/n64-c/lesson/abi-fifth-arg) — abi, arguments, stack-args - [Float Arguments: fa0 and fa1](https://decomp-academy.dev/courses/n64-c/lesson/abi-float-args) — abi, float-args, fpu - [The Third Float Rides a GPR](https://decomp-academy.dev/courses/n64-c/lesson/abi-third-float-arg) — abi, float-args, fpu, stack-args - [Calling Out: The Minimal Stack Frame](https://decomp-academy.dev/courses/n64-c/lesson/abi-nonleaf-frame) — abi, calls, frames, stack - [The Argument in the Delay Slot](https://decomp-academy.dev/courses/n64-c/lesson/abi-delay-slot-arg) — abi, calls, delay-slots, arguments - [Passing More Than Four](https://decomp-academy.dev/courses/n64-c/lesson/abi-caller-stack-args) — abi, calls, stack-args, frames - [Homing: The Four Shadow Slots](https://decomp-academy.dev/courses/n64-c/lesson/abi-arg-homing) — abi, homing, arguments - [Narrow Arguments Re-Extend Themselves](https://decomp-academy.dev/courses/n64-c/lesson/abi-narrow-args) — abi, homing, narrow-types, arguments - [Keeping a Value Across a Call](https://decomp-academy.dev/courses/n64-c/lesson/abi-keep-across-call) — abi, calls, homing, frames - [Feeding One Call Into the Next](https://decomp-academy.dev/courses/n64-c/lesson/abi-chain-calls) — abi, calls, delay-slots - [When the First Result Must Survive](https://decomp-academy.dev/courses/n64-c/lesson/abi-two-results) — abi, calls, frames, locals - [Saved Registers: A Loop Around a Call](https://decomp-academy.dev/courses/n64-c/lesson/abi-loop-call-sregs) — abi, saved-registers, loops, calls - [Stack Arguments, Seen Through Your Own Frame](https://decomp-academy.dev/courses/n64-c/lesson/abi-incoming-after-frame) — abi, stack-args, frames, homing, calls - [Capstone: The Calling Convention, End to End](https://decomp-academy.dev/courses/n64-c/lesson/abi-capstone) — abi, calls, homing, frames, capstone ##### Globals & %hi/%lo — Reading and writing global state through lui address pairs, relocations, arrays, and statics. - [Reading a Global](https://decomp-academy.dev/courses/n64-c/lesson/globals-read-int) — globals, hi-lo, relocations - [How %hi and %lo Really Work](https://decomp-academy.dev/courses/n64-c/lesson/globals-hi-lo-machinery) — hi-lo, relocations, linker, mental-model - [Writing a Global](https://decomp-academy.dev/courses/n64-c/lesson/globals-write-int) — globals, hi-lo, stores - [Read, Modify, Write](https://decomp-academy.dev/courses/n64-c/lesson/globals-read-modify-write) — globals, hi-lo, rmw - [Narrow Globals and the Load Alphabet](https://decomp-academy.dev/courses/n64-c/lesson/globals-narrow) — globals, narrow-types, loads - [Float Globals Load Straight Into the FPU](https://decomp-academy.dev/courses/n64-c/lesson/globals-float) — globals, fpu, hi-lo - [No Memory Op at All: Taking an Address](https://decomp-academy.dev/courses/n64-c/lesson/globals-address-of) — globals, hi-lo, pointers, arrays - [Indexing a Global Array](https://decomp-academy.dev/courses/n64-c/lesson/globals-array-index) — globals, arrays, hi-lo, indexing - [A Constant Index Melts Into the Name](https://decomp-academy.dev/courses/n64-c/lesson/globals-array-const-index) — globals, arrays, hi-lo, relocations - [Statics: The Global With No Name](https://decomp-academy.dev/courses/n64-c/lesson/globals-statics) — globals, statics, bss, rmw - [Two Globals, Interleaved](https://decomp-academy.dev/courses/n64-c/lesson/globals-two-globals) — globals, hi-lo, scheduling - [Capstone: Global State Like a Real Game](https://decomp-academy.dev/courses/n64-c/lesson/globals-capstone) — globals, hi-lo, rmw, capstone ##### The IDO Optimizer — Delay-slot packing, hazard nops, scheduling, and what -O2 -g3 does to your C. - [-O2 -g3: Why the Code Looks Like This](https://decomp-academy.dev/courses/n64-c/lesson/opt-g3-story) — optimizer, debug-level, fingerprints, mental-model - [The Two-Slot Window After mflo](https://decomp-academy.dev/courses/n64-c/lesson/opt-mflo-window) — optimizer, hi-lo, hazards, multiply - [Feeding the Multiplier](https://decomp-academy.dev/courses/n64-c/lesson/opt-operands-first) — optimizer, scheduling, multiply, hi-lo - [Crossing to the FPU: mtc1 and Its nop](https://decomp-academy.dev/courses/n64-c/lesson/opt-mtc1-hazard) — optimizer, floats, hazards, conversion - [c.lt, Then Wait, Then Branch](https://decomp-academy.dev/courses/n64-c/lesson/opt-float-compare) — optimizer, floats, hazards, branch-likely - [Branch Likely: The Slot That Sometimes Runs](https://decomp-academy.dev/courses/n64-c/lesson/opt-branch-likely) — optimizer, branch-likely, delay-slots, conditionals - [The ×4 Unroller](https://decomp-academy.dev/courses/n64-c/lesson/opt-unroll-const) — optimizer, loops, unrolling, arrays - [Unrolling an Unknown Count](https://decomp-academy.dev/courses/n64-c/lesson/opt-unroll-variable) — optimizer, loops, unrolling, fingerprints - [Multiply, Demoted to Add](https://decomp-academy.dev/courses/n64-c/lesson/opt-strength-reduction) — optimizer, loops, strength-reduction, fingerprints - [Regrouped Behind Your Back](https://decomp-academy.dev/courses/n64-c/lesson/opt-reassociation) — optimizer, reassociation, arithmetic, fingerprints - [Compute Once, Use Twice](https://decomp-academy.dev/courses/n64-c/lesson/opt-cse) — optimizer, cse, arithmetic - [Reading a Different Dialect: -O1](https://decomp-academy.dev/courses/n64-c/lesson/opt-level-o1) — optimizer, debug-level, loops, stack - [Full Speed: -O2 Without the Debugger](https://decomp-academy.dev/courses/n64-c/lesson/opt-level-o2g0) — optimizer, debug-level, calls, scheduling - [Capstone: Fingerprints, All at Once](https://decomp-academy.dev/courses/n64-c/lesson/opt-capstone) — optimizer, loops, unrolling, multiply, capstone ##### Advanced Idioms — Jump tables, compare chains, division traps, volatile, and enums — the last shapes between you and real code. - [The Jump Table](https://decomp-academy.dev/courses/n64-c/lesson/adv-jump-table) — switch, jump-table, control-flow - [Cases That Do Work](https://decomp-academy.dev/courses/n64-c/lesson/adv-switch-actions) — switch, jump-table, control-flow - [Tables That Don't Start at Zero](https://decomp-academy.dev/courses/n64-c/lesson/adv-offset-table) — switch, jump-table, control-flow - [Sparse Cases: The Compare Chain](https://decomp-academy.dev/courses/n64-c/lesson/adv-sparse-chain) — switch, control-flow, compare-chain - [The Missing break](https://decomp-academy.dev/courses/n64-c/lesson/adv-fallthrough) — switch, control-flow, fallthrough, fingerprints - [Dividing by a Variable](https://decomp-academy.dev/courses/n64-c/lesson/adv-var-division) — divide, hi-lo, traps, fingerprints - [volatile: Every Access Is Real](https://decomp-academy.dev/courses/n64-c/lesson/adv-volatile) — volatile, globals, cse, hardware - [Spinning on Hardware](https://decomp-academy.dev/courses/n64-c/lesson/adv-poll-loop) — volatile, loops, branch-likely, hardware - [Enums Are Just Numbers](https://decomp-academy.dev/courses/n64-c/lesson/adv-enums) — enums, conditionals, control-flow - [Capstone: The State Machine](https://decomp-academy.dev/courses/n64-c/lesson/adv-state-capstone) — switch, globals, control-flow, capstone ##### 64-bit Integers — One s64, two registers — pairing, carry chains, and the millicode helpers. - [s64: One Value, Two Registers](https://decomp-academy.dev/courses/n64-c/lesson/int64-register-pairing) — int64, abi, register-pairing, mental-model - [Two Halves, No Crosstalk](https://decomp-academy.dev/courses/n64-c/lesson/int64-bitwise-halves) — int64, bitwise, register-pairing - [The Carry Chain](https://decomp-academy.dev/courses/n64-c/lesson/int64-carry-chain) — int64, arithmetic, carry, register-pairing - [Carrying a Constant](https://decomp-academy.dev/courses/n64-c/lesson/int64-add-constant) — int64, arithmetic, carry, immediates - [Widening: Making a High Half from Nothing](https://decomp-academy.dev/courses/n64-c/lesson/int64-widening) — int64, casts, sign-extension - [Truncation: The High Half Vanishes](https://decomp-academy.dev/courses/n64-c/lesson/int64-truncation) — int64, casts, truncation - [The Skipped Register](https://decomp-academy.dev/courses/n64-c/lesson/int64-mixed-args) — int64, abi, alignment, sign-extension - [Are They Equal? xor, or, sltiu](https://decomp-academy.dev/courses/n64-c/lesson/int64-equality) — int64, comparison, branchless - [Less, Greater: The Two-Level Compare](https://decomp-academy.dev/courses/n64-c/lesson/int64-ordered-compare) — int64, comparison, branches - [Millicode: Shifting by Calling](https://decomp-academy.dev/courses/n64-c/lesson/int64-shift-const) — int64, shifts, millicode, calls - [Shifting by a Variable](https://decomp-academy.dev/courses/n64-c/lesson/int64-shift-var) — int64, shifts, millicode, sign-extension - [__ll_mul: The 64-bit Multiply](https://decomp-academy.dev/courses/n64-c/lesson/int64-multiply) — int64, multiply, millicode, calls - [The Divide Family](https://decomp-academy.dev/courses/n64-c/lesson/int64-divide-family) — int64, divide, millicode, calls - [Capstone: 64 Bits, Assembled](https://decomp-academy.dev/courses/n64-c/lesson/int64-capstone) — int64, millicode, carry, capstone ##### The Whole ABI at Once — Realistic function bodies — frames, globals, optimizer fingerprints, and 64-bit math, all in one place. - [A Global Rides Through a Call](https://decomp-academy.dev/courses/n64-c/lesson/finale-global-through-call) — globals, calls, frames, hi-lo - [The Unroller Meets a Global Array](https://decomp-academy.dev/courses/n64-c/lesson/finale-unrolled-global-loop) — globals, loops, unrolling, hi-lo, optimizer - [A Float Global and a Baked-in Constant](https://decomp-academy.dev/courses/n64-c/lesson/finale-float-global) — globals, floats, hi-lo, fingerprints - [A 64-bit Global, Read-Modify-Write](https://decomp-academy.dev/courses/n64-c/lesson/finale-int64-global) — int64, globals, carry, hi-lo, sign-extension - [Grand Capstone: One Real Function](https://decomp-academy.dev/courses/n64-c/lesson/finale-grand-capstone) — globals, calls, hi-lo, branches, capstone #### Proving ground — Pull together everything you've learned on functions that feel like the real thing. ##### Real-World Mastery — Fourteen end-to-end functions that put every technique from the course to work. - [Shipped Code: Is the Queue Full?](https://decomp-academy.dev/courses/n64-c/lesson/mastery-queue-is-full) — real-code, structs, booleans - [The Intrusive List: Prepend](https://decomp-academy.dev/courses/n64-c/lesson/mastery-list-prepend) — real-code, pointers, structs - [Bits Into Bytes](https://decomp-academy.dev/courses/n64-c/lesson/mastery-bitstream-init) — real-code, bitwise, delay-slots - [The Dot Product, As They Wrote It](https://decomp-academy.dev/courses/n64-c/lesson/mastery-vec3-dot) — real-code, floats, fpu, operand-order - [The Cross Product](https://decomp-academy.dev/courses/n64-c/lesson/mastery-vec3-cross) — real-code, floats, structs - [Append, and the Order of an Add](https://decomp-academy.dev/courses/n64-c/lesson/mastery-list-append) — real-code, pointers, loops, operand-order - [Enqueue: bcopy and the Wrap-Around](https://decomp-academy.dev/courses/n64-c/lesson/mastery-queue-enqueue) — real-code, calls, structs, multiply - [The Joystick Deadzone](https://decomp-academy.dev/courses/n64-c/lesson/mastery-stick-deadzone) — real-code, narrow-types, branches, globals - [Footstep Sounds, Table-Dispatched](https://decomp-academy.dev/courses/n64-c/lesson/mastery-footstep-banks) — real-code, switch, jump-table, hi-lo - [The Ghost of a Debug Print](https://decomp-academy.dev/courses/n64-c/lesson/mastery-bitstream-read) — real-code, loops, bitwise, dead-code - [Deleting From the Middle](https://decomp-academy.dev/courses/n64-c/lesson/mastery-stack-delete) — real-code, loops, calls, saved-registers - [Capstone: The Reflection Vector](https://decomp-academy.dev/courses/n64-c/lesson/mastery-vec3-reflect) — real-code, floats, control-flow, statement-order - [Capstone: The B-Spline Curve](https://decomp-academy.dev/courses/n64-c/lesson/mastery-bspline) — real-code, floats, rodata, frames - [Grand Capstone: Footprints in a Moving World](https://decomp-academy.dev/courses/n64-c/lesson/mastery-footprint-scroll) — real-code, unrolling, floats, globals, capstone