- macros/README.md
- Add ### MOD section documenting the previously-undocumented MOD
macro (src_a, src_b, dest, scratch → sdiv/msub composition).
Canonical apple-linux-convergence.S has defined MOD since at least
the sync-script enforcement work (3144bc6); README drifted from it.
- Rewrite variadic cross-reference to link BOTH more/varargs/README.md
(the dedicated chapter) and more/apple_silicon/README.md (the
Apple/Linux divergence discussion). Original pointed only at
apple_silicon, which undersold the standalone varargs chapter.
- Grammar: "Thank you to u/TNorthover for nudge" → "for the nudge".
- not_written_yet.md
- Capitalize GitHub.
Rejected alternatives: (a) removing MOD from canonical instead of
documenting it — rejected per author direction, MOD is useful; (b)
repointing the variadic link to varargs only — rejected, the Apple
Silicon page's divergence discussion remains directly relevant in the
macros context.
Proofing status (NAS): LICENSE.md and not_written_yet.md flipped to
[reviewed]; macros/README.md flipped to [revised].
Full top-to-bottom proofread of the root README.
Narrow fixes (typos, grammar, formatting, broken syntax):
- Two malformed `</br>` closing tags replaced with `<br/>`.
- "See the [here](...)" → "See [this chapter](...) for..." (the
previous phrasing had a dangling article and a preposition that
did not parse cleanly).
- Stray angle brackets around a URL in the "Here is a link to 'a'
main instruction set page" sentence removed (the brackets created
a redundant autolink inside an already-formed markdown link).
- "quite straight forward" → "straightforward" (one word).
- "whose job it is turn high level languages" → inserted the
missing "to".
- Added backticks around "gcc" and "g++" in the "We use gcc and g++
directly..." sentence for consistency with every other reference
to those tools in the file.
- `main.s` → `main.S` in the "Suppose main() is implemented in
assembly language..." paragraph; the surrounding prose teaches
the capital-S convention, and the lowercase `.s` was contradicting
the very point being made.
- "for handing `#include`" → "for handling `#include`".
- "a general tool can is used by other languages" → "a general tool
used by other languages" (extra "can is" was clearly a mid-edit
remnant).
Substantive corrections:
- The linker description listed ".dlls on Windows" as an example of
a statically-linked library file. DLLs are the canonical dynamic
linking format on Windows; static on Windows is .lib. The sentence
now correctly separates the two categories: `.a` (Linux) and `.lib`
(Windows) for static, `.so` (Linux) and `.dll` (Windows) for
dynamic.
- The "Twenty twenty three marks Perry's 19th year teaching..."
paragraph was three years stale and referenced an ongoing count
that had since ended. Replaced with a year-agnostic retirement
statement summing the nineteen total years (ten UW Madison plus
nine Carthage). The new phrasing will not age.
- Normalized "pre-processor" (hyphenated) to "preprocessor" (one
word) throughout the "C Preprocessor" subsection, matching the
four unhyphenated uses that appeared earlier in the same document
and aligning with common modern style. Section heading updated to
match.
Expanded author bio:
- Added a new paragraph in "About The Author" surfacing credentials
directly relevant to this book's systems/assembly audience: the
undergraduate V6 Unix kernel study on a PDP-11/60, the subsequent
Bell Labs Unix-internals teaching role, priority on the earliest
known software keylogger, the 1985 appearance on Fred Fish Disk #1
(the first volume of the longest-running public-domain software
library in personal-computing history), named references to the
ASDG / TAD / ADPro / Elastic Reality commercial lineage, and the
"Loaders → Operators → Savers" architectural throughline that has
now evolved into the "Sensor → Operator → Emitter" pipeline in
the author's current open-source GlowUp project (home automation
broader than just lighting). The GlowUp repo at
github.com/pkivolowitz/lifx is linked.
Rejected alternatives:
- Rolling the "19th year" numbers forward to 2026 rather than
switching to the retirement framing — rejected because the count
is no longer ongoing and any year-pinned phrasing will age the
same way again.
- A Front-Matter-level authorship / biography section rather than
an addition to the existing "About The Author" section — rejected
as tonally too heavy; biography belongs where biography already
lives.
- Fixing the DLL/static-linking text by simply renaming "statically
linked" to "dynamically linked" for the .dll example — rejected
because the surrounding sentence teaches the concept of library
linking and benefits from showing both categories side by side.
No test coverage applies; this is prose.
New subsection "A Note on Authorship and AI Assistance" at the end of
"About The Author" states that as of 19 April 2026 the author has
begun using an AI assistant as a writing and editing aid on this
book, and that all material preceding that date was produced unaided.
Points the reader at git history and the scripts/ and .github/
tooling landed around the same time as the durable markers for
distinguishing AI-assisted from unaided work going forward.
Placement rationale: "About The Author" is already the section
carrying author-identity and first-person voice, so the disclosure
lives where a reader with any interest in authorship provenance
naturally scrolls. The alternative (a Front Matter subsection) was
considered and rejected as tonally too heavy for a note that exists
mainly to answer a future question, not to front-load caveats ahead
of the book's self-description.
No test coverage applies; this is prose.
Part of #33.
The v6.S listing in the hello_world chapter introduces the PUSH_P,
PUSH_R, POP_P and POP_R macros without explicitly telling the reader
what the _P and _R suffixes stand for. For a reader reading the
chapter in order, the mapping is derivable: the book established
stp = "store pair" about 260 lines earlier, and the _R suffix falls
out by parallel with str. But a reader who jumped straight to v6.S
without reading the stp explanation (as Atcold did in issue #33) has
no such anchor and is left guessing.
One sentence at the "The push and pop macros simply save typing"
paragraph closes the gap: it names the _P / _R suffixes, connects
them to the already-taught stp / str convention, and costs a skimmer
nothing. The macro names themselves are unchanged; they were already
fine for an in-order reader, and renaming would have churned every
.S file in the book.
The repository ships a copy of apple-linux-convergence.S in each
chapter directory that demonstrates assembly (11 copies at last count,
plus the canonical one in macros/) so that readers browsing or
downloading a single chapter from GitHub have the macros sitting
right next to the sources that use them. That self-containment is
worth keeping. Manual synchronization of 12 copies on every macro
edit is not: all 11 are currently byte-identical to the canonical,
but the first drift is a matter of when, not if, and diagnosing
"which chapter broke when I added a new macro" after the fact is
a bad time.
This commit turns "the copies are in sync" from a hope into a
machine-enforced invariant:
- scripts/sync-macros.sh: walks macros/*.S, finds every file with
the same basename anywhere else in the repo (excluding .git/ and
macros/ itself), and overwrites any copy that differs. Idempotent;
prints only the files it actually changed plus a summary. Uses
only POSIX tools (find, cmp, cp, basename) plus bash builtins
under a #!/usr/bin/env bash shebang. Verified working under both
macOS bash 3.2.57 and zsh 5.9 on clean-tree and drift-repair
paths.
- .github/workflows/check-macros.yml: runs the sync script on every
push and pull request, then fails the job if git diff --exit-code
shows the script produced any uncommitted change. The failure
message tells the author exactly what to do (run the script
locally, commit the result).
- macros/README.md: new "Source of truth" section marking the
chapter copies as derived artifacts, pointing editors at the
sync script, and stating that CI enforces the invariant.
Rejected alternatives:
- Symlinking each chapter copy to macros/apple-linux-convergence.S.
Cheapest option (zero infrastructure) and git handles symlinks
natively, but Windows checkouts without Developer Mode replace
the symlink with a plain-text file containing the target path.
This book's audience is overwhelmingly Linux and Apple Silicon,
so the Windows hazard is mostly theoretical, but a sync-and-check
approach works in every clone environment and makes the
source-of-truth relationship explicit rather than implicit in a
filesystem feature.
- Having each chapter .include the canonical file via a relative
path. Breaks the "self-contained chapter" property the copies
exist to preserve; a reader who downloads one chapter gets a
broken build because macros/ is not beside it.
- Making the copies build-time artifacts (generated by make, not
committed). Same problem: a reader browsing one chapter on
GitHub no longer sees the macro file they need.
Tests:
- ./scripts/sync-macros.sh run on the current tree reports
"macros already in sync (11 chapter copies checked)" and exits 0.
- Injecting a trailing-line perturbation into a chapter copy and
re-running the script: detects the drift, reports "synced: <path>",
and restores the file to canonical. Verified under both bash and
zsh, both paths.
Closes#22.
The alignment chapter's hex dump examples (e.g. "0011 eeff ccdd aabb"
for a little-endian long initialized to 0xaabbccddeeff0011) are correct
under the default hexdump(1) output convention: bytes grouped into
16-bit little-endian words, each word printed most-significant byte
first. But the chapter never told the reader which convention was in
use, so a reader reproducing the example with xxd or hexdump -C (both
byte-oriented, showing raw memory order) would get a different-looking
result and conclude the book had an endianness bug. That is exactly
what issue #22 reported, and it is also part of what the #33 filer
flagged as "there are no instructions about how to do such a thing"
for hex dumps in this chapter.
Fix: one new subsection "A Note on Hex Dumps" placed before Example 1,
stating the convention explicitly and warning xxd / hexdump -C users
that the bytes within each pair will appear swapped relative to the
examples. The examples themselves are unchanged; they were already
self-consistent under the word-oriented convention.
Rejected alternative: rewriting all the examples in byte-oriented
(xxd) form. That would have matched what most modern readers reach
for, but would also have required regenerating every hex dump in the
chapter and losing continuity with any reader who already absorbed
the current notation. A single explanatory paragraph is less invasive
and teaches the distinction, which is useful in its own right.
No test coverage applies; this is prose.