Calling Assembly from C and C++¶
Let C or C++ handle input and reporting while a small assembly function implements one explicit contract. Link the same assembly object to both callers.
Course examples on GitHub
Before you start¶
Complete functions and the ABI. Basic C declarations are needed here; the optional C++ caller uses only a wrapper and C linkage.
Outcome: build separate objects and distinguish a link-name problem from an ABI or bounds problem. Work in a fresh directory on the Pi.
Define the contract first¶
add_u64(a, b) returns their sum modulo 2^64. It has no pointers, allocation, exceptions or hardware access. Fixed-width types make the intended widths explicit; they do not automatically fix an incorrect assembly implementation.
The symbol table should expose add_u64. The compiler checks declarations at C call sites; it does not prove that the assembly agrees.
Call the same object from C++¶
Save this alternative driver; it has its own main, so do not link both drivers together.
extern "C" controls language linkage; it does not transform an arbitrary class into a portable layout or make exceptions safe across hand-written frames. Keep the boundary simple. A member function's implicit object argument, struct return and varargs need their own ABI analysis, not a copied integer example.
Diagnose the right layer¶
| Failure | Inspect |
|---|---|
| Undefined reference | Exact symbol spelling, C++ mangling, missing object |
| Multiple definition of main | Only one alternative driver per executable |
| Correct link, wrong result | Signature, widths, argument order and preservation |
| Crash with pointers | Accessible storage, lifetime and length contract |
| Exec format error | Object and executable target architecture |
Do not add sudo to fix a link error. Do not add device addresses or memory mapping to establish basic interoperability.
Where hardware fits¶
GPIO register maps vary by SoC and controller. A Linux user-space assembly course is not a reason to bypass kernel interfaces. After this course, use the separate C++ Hardware Programming course for wiring, line ownership and safe kernel-supported access. The old mixed GPIO/ABI lesson is replaced by this explicit, hardware-independent boundary.
Check your understanding¶
Why can a C++ declaration with the wrong type still link to this assembly symbol?
Compare your reasoning
The linker matches symbol names, not the full source-level contract of a hand-written assembly body. Matching names are necessary but do not prove widths or semantics.
Continue the course¶
Previous: Functions, Stack and the ABI · Course roadmap · Next: Debugging with GDB