Expand description
Instruction encoders, the integrated assembler, inline assembly and relaxation.
Design: spec/11-asm-objects-debug.md. Layer rank 11, see spec/18-package-layout.md.
§Status
What is written are the two things a compiler does with a machine function: the assembly text
-S produces, which is print(), and the bytes of a text section, which is assemble.
Section 11.1 asks for one instruction description behind both, and there is one: the walk over
a function is the same walk in both files, reading the same list out of rucc-target, and the
only difference is whether an instruction is written down by name or handed to the encoder. So
the listing and the object file cannot come to disagree about what an instruction is.
What assemble hands back with the bytes is what the linker has to be told: where each
function starts and how long it is, and every place in the bytes that names something this
file does not contain. The jumps inside a function are not among them, because by the end of a
function every block has a place and they are filled in here.
The variables a file defines are here for the same reason and in the same shape. globals is
the one walk over a module’s globals, and what it gives back is a list of pieces that
print() writes down as directives and Globals::image writes down as bytes, so a .long
in a listing and the four bytes in the object beside it cannot come to disagree either. Where a
variable goes is worked out there rather than named by the front end, and what a section is
called is the object format’s business.
read is the other direction: a file of assembly that somebody else wrote, turned into the
sections and names an object is written from. The directives and the labels are one half of it
and the instructions are the other, and a mnemonic with no bytes behind it is refused by name
with its line number rather than skipped. Nothing there describes the machine a second time:
the bytes of an instruction come from the one encoder in rucc-target that the compiler’s own
output goes through, so a file this assembles and a file this compiles cannot disagree about
what an instruction is. Branch relaxation is not here yet, so a jump is four bytes of distance
whether it needs them or not, which is correct and longer than gas would have written.
Every crate in the workspace is published, and publishing implies a promise. This one is
tier 3: its Rust API is explicitly unstable and will change without a major version bump.
Depend on the rucc binary’s behaviour, not on this.
Structs§
- Globals
- Every variable a module defines, laid out.
- Trouble
- A file this could not read, and where in it.
- Variable
- One global variable, as the pieces of its image and what the linker is told about it.
Enums§
- Directives
- The directives one object format wraps a function in.
- Error
- A function this compiler could not write out as assembly.
- Piece
- As much of an image as one directive says.
Constants§
- MILESTONE
- The milestone in
spec/17-milestones.mdthat fills this crate in.
Functions§
- aliases
- Every second name a module gives something, in the order it gave them.
- assemble
- Every function, as the bytes of a text section.
- globals
- Every variable a module defines, laid out.
- Every function and every variable, as assembly text.
- read
- What a file of assembly says, as the sections and names an object file is written from.