-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Native Assembler: Improvements, Tweaks, Enhancements #7561
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Pending the inevitable arguments against it, I'm in full support of this. I think some of the specific syntax needs to be altered, but aside from that, a "Zig-flavored asm" makes a great deal of sense IMO. This also conveniently paves the way for asm files per input file instead of per compilation unit (thanks to .use), which allows the assembling pass to be parallelized with a single process per asm file by build.zig instead of needing tracking or dependency code inside of the assembler. This is a great parallel (pun intended) to a Makefile with a bunch of objects built from asm. I think it might even be able to integrate with incremental compilation; if we have our own syntax, we can just effectively pretend that a .s file is a .zig file with a single |
Which syntax, specifically? |
@EleanorNB Actually, most of the syntax is fine on a second look, I think.
This means multiple input asm files can be compiled into one compilation unit? and |
That's right. Zig has multi-file compilation units, we might as well use them. (That's also the only way that |
If you're serious about making a new object format, it'd probably be easier to add support to an existing OS :P |
@EleanorNB Would you intend macro support in the asm? If the goal is to be able to write asm directly, I think that makes sense (and a simple macro processor is pretty straightforward). On the other hand, "macro support" could be a build.zig feature instead, using an extension to build.zig that parses the asm, performs macro replacement, and gives the resultant file as an input instead of the source. This removes the complexity from the compiler, while still allowing asm programmers to add support themselves in a manner best suited to their project. It's worth noting that you could technically do that for Zig code as well, which could theoretically be used to replace some expensive comptime calls with cheap textual substitution. I can already hear people screaming in revulsion at the idea - but the point isn't, "hey, this is a good idea!" it's that it can be done independently of the compiler! The advantages of a native build system :) |
@pixelherodev Some examples, how you intent the assembler to look and what parsing+checking synax+type complexity you intend, would be great. There is a tradeoff between syntax+type complexity = compile-time speed, functional complexity and safety classes. |
Split out from #2081 (comment) . See also #5241 for inline assembly improvements.
Zig Native Assembler
For system interfacing without libc in LLVM-less builds, we will need our own inline assembler. From there, it's not much more work to have a standalone assembler as well. This presents us an opportunity to make some improvements. It won't be wise to stray too far, though, as people will need to port their existing code.
Proposed Changes
.
and symbols end with:
.label:
/b .label
,_:
/b _(+|-)+
(nob _
-- ambiguous).pub sym:
,.use sym
for sharing symbols within a compilation unit.export sym:
,.extern ("mod")? sym
for sharing symbols between objects.comm
or.global
.end
takes a symbol(s):.end sym1, sym2
==.size sym1, (. - sym1) [\n] .size sym2, (. - sym2)
; all non-local symbols must be.end
ed; replaces.size
.end
boundaries0x8000 pin:
,0xff00:
-- only possible at the start of a coherent region (all previous symbols have been.end
ed); linker will detect clashes/range errorsuse
keyword, to access.pub
symbols within the compilation unit:use const func: fn callconv(.c) (u64, bool) u64;
Notes
.pub
/.use
take advantage of Zig's compilation units:.pub
symbols are not necessarily exported, and.export
symbols are not necessarily public. Symbols from pre-compiled object files cannot be.use
d; they must be.extern
al (see below)..pub
symbols populate a single global namespace; the amorphous organisation permitted by assembly means a strictly hierarchical symbol-sharing model would be untenable. Explicit.use
at least makes this much more manageable..extern "mod"
provides some primitive namespacing for libraries, as with Zigextern
-- without this, making the use of multiple libraries tenable requires a single global namespace for every symbol in every library on the system. The interpretation ofmod
is left to the linker, to facilitate versioning of libraries or different library paths; lack of "mod" is always taken to mean another explicit input object file (i.e. argument tozig build-(exe|lib)
. An unresolved symbol is a compile error..pub
lic and.export
ed symbols must be declared as such at the symbol definition site, i.e..pub sym:
both declares the symbolsym
and marks it public, and there is no way to separate these actions. This facilitates locating such a symbol by a simple global text search..global
makes symbols impossible to track down,.common
glosses over potential naming errors; their functionality is subsumed by.pub
/.use
..end
was chosen rather than some kind of hierarchical structure or dividing by non-local symbols to allow overlapping of symbols, as well as sequencing:This presents an interesting edge case: a local label may be dropped by a non-local symbol while its use would still be valid. I'm not aware of a clean solution to this.
@sImport()
, but the need for strong typing would have made it untenable. Collecting all public symbols into a namespace wouldn't have helped, for the same reason: since builtins will be required anyway, and the lack of explicit source file dependencies means assembly building will have to be coordinated by build.zig anyway, there is no harm in accessing symbols individually. (Note: this still only applies to symbols within the same compilation unit;.export
ed symbols from prebuilt objects still come through Zigextern
, as usual.)export
/.extern
; this is annoying, however, as Zig is typically the driver of asm and not the other way around, and inline asm with Enhancement: New Inline Assembly #5241 makes any structure possible if need be, it is considered acceptable.The text was updated successfully, but these errors were encountered: