✨ Disclosure: this tutorial was drafted with AI assistance. Every technical claim is verified and source-traced in the linked repository.
AI assistants are confident about assembly — and wrong in specific, repeatable ways. They invent mnemonics that do not exist, flip AT&T/Intel operand order, silently drop immediates, and misread bytes. When we audited real incidents, the failures shared a signature: the code looks plausible and never errors.
The fix isn't "be more careful". It's a mechanical gate you can run in seconds.
The gate: assemble → disassemble → compare
# AT&T / GNU as, x86-64
gcc -c sample.s && objdump -d sample.o
# Intel syntax
gcc -c -masm=intel sample.s && objdump -d -M intel sample.o
If the disassembly does not match what you wrote — same mnemonic, same operands, same size — you did not write that instruction. Three real cases this catches:
1. A mnemonic that does not exist
movqad is not an instruction. The assembler rejects it — so far, so good. The dangerous ones compile.
2. A silently truncated immediate
imul eax, eax, 38 ; assembles to: 69 c0 00 00 00 00
The 38 is silently dropped by the parser — this is the bug class behind BBoeOS PR#584. The code compiles. The intent is gone.
3. A dialect swap
-masm=intel flips the operand order (mov eax, [rax] vs mov (%rax), %eax). Mixing AT&T and Intel in one file silently changes semantics.
Why "it compiles" is not enough
Compiling proves your syntax fits some grammar. It does not prove the encoding matches your intent. LLM-based disassembly gets exact instruction matches right about 14% of the time; "corrected" decompilations are right about 37%. The confidence-to-correctness gap is exactly where the expensive bugs live.
Rules to live by
- Never assert an instruction, encoding, or length from memory. Assemble it.
- Pin the syntax dialect explicitly. Never mix AT&T and Intel.
- Check the raw bytes for unusual instructions against the manual (Intel SDM, ARM ARM, RISC-V ISA).
- If the toolchain isn't available, say UNVERIFIED and give the command that would check.
The same discipline applies everywhere
Verify real parallelism (thread counts + wall time, not thread-safe syntax). Verify the API actually exists (cargo search, not memory). Verify your verification — a harness that can't fail is not evidence.
📦 The repository — actively updated
The full failure catalog and the skills that encode these gates live in
https://github.com/TrothByte/low-level-skills-trothbyte — 124 verified skills for
C, C++, Rust, assembly, kernel, embedded, Zig, GPU, reverse engineering, and build systems.
-
65 of 124 skills are executed on real toolchains (GCC 16.1, rustc 1.97, GDB, objdump, CMake/Ninja); the rest are honestly marked
researchedwith exact verification commands. - Every claim is source-traced: claim → primary source → section → skill (177 primary sources).
- The repository is continuously updated — new failure classes and skills are added as incidents are catalogued, and the whole library re-validates on every change:
git clone https://github.com/TrothByte/low-level-skills-trothbyte
python tools/validate.py # 124 skills + registry + 177 sources, gated in seconds
Also installable via npx skills add TrothByte/low-level-skills-trothbyte or as a Claude Code plugin marketplace.
Found a failure we haven't catalogued? The repo accepts issues — every new skill must be source-traced and differentiated from the existing 124. Watch the repository to get updates as it grows.
Top comments (0)