# 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: 271 hands-on lessons across 2 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) functions into byte-matching C, graded in your browser by agbcc. #### Warm-up — Learn to read the Thumb machine ##### ARM Foundations — The ARM7TDMI registers, the Thumb instruction set, and reading agbcc output. - [Arguments Live in Registers 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 - [Immediates: Math With Constants](https://decomp-academy.dev/courses/gba/lesson/gba-foundations-immediate) — arithmetic, immediates - [Negation in One Instruction](https://decomp-academy.dev/courses/gba/lesson/gba-foundations-negate) — arithmetic, registers #### Core Idioms — Medium-weight Thumb patterns the real functions build on ##### Thumb Idioms — Signed shifts, clamps, and the patterns real functions are built from. - [Signed Division by a Power of Two](https://decomp-academy.dev/courses/gba/lesson/gba-idioms-signed-shift) — arithmetic, shifts - [Clamping with a Conditional Skip](https://decomp-academy.dev/courses/gba/lesson/gba-idioms-clamp) — control-flow, comparison #### Proving ground — Real Klonoa: Empire of Dreams functions, start to finish ##### Real-World Mastery — Authentic Klonoa: Empire of Dreams functions, from idioms to full functions. - [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