Please document the inline assembly syntax

As it currently stands, the inline assembly syntax isn’t documented at all, other than providing one example and that’s about it. The asm documentation refers you to the LLVM language reference manual and the GCC documentation, but this definitely is far too little documentation on the matter given that the assembly syntax Zig uses is (not) exactly AT&T or GCC-style template syntax, and that in turn has lead me to a ton of frustration with it because I have nothing to go by, other than examples, which aren’t enough and do things in all kinds of ways. So please, please just document it, and then at the end say “things will change sometime in the future with output/input/clobbers, but you can use this for now” or something to that effect.

Edit: If this isn’t the right place to post this (Idk if Zig contributors check here) I can post it elsewhere. But the issue I’m struggling with is something that I (didn’t think) would be too complicated to do:

pub inline fn getPageDirectoryAddress() u64 {
    return switch (builtin.cpu.arch) {
        .x86, .x86_64 => asm volatile ("movq %%cr3, %[value]"
            : [value] "=&r" (-> u64),
        ),
        else => 0,
    };
}

I’ve tried using the =r constraint and it still fails – causing a #GP exception regardless of what I specify as the constraint. I’ve tried flipping the operands (I’m assuming that this is using AT&T syntax and not Intel syntax) and it doesn’t like that either. (Though flipped, if this is in fact AT&T syntax, that’d make sense, since it’d be moving whatever register was allocated to CR3.) I’m completely confused and unsure what to do, and the lack of documentation isn’t helping things, hence my mini-rant above (sorry about that).

3 Likes

I managed to figure it out but I still think that the documentation would be good to have as a reference.

Welcome!

Zig contributors do check here and there’s certainly a lot of documentation to still be done. They know this and are working on it

Do you mind posting your working example and any resources that helped you for those who find this later on?

I’ll actually have to be diving into inline assembly myself soon and will document what I can

I think your mini-rant is well intended. The Zig documentation has been receiving many updates as of late (even to the core language itself) so there has been some confusion surrounding this lately. Please note that we’re anticipating a new version on August 3rd of this year so many things are shifting around as of now: How far away is 0.11 really? - #10 by Durobot

Have you considered making a formal proposal on the Zig github? You may want to browse through the current proposals and if you don’t see what you’re looking for then perhaps create one: Issues · ziglang/zig · GitHub

Also, welcome to the forum!

1 Like

Hi there,

My solution was:

pub inline fn getPageDirectoryAddress() u64 {
    return switch (builtin.cpu.arch) {
        .x86, .x86_64 => asm volatile ("movq %%cr3, %[value]"
            : [value] "=&r" (-> u64),
        ),
        else => 0,
    };
}

It turned out that a different function was causing the problem, not this particular function. Now I just have to figure out how to set up the GDT and IDT… I’d like to avoid separate .S files if possible, but I might not have much of a choice for the GDT at least, since adjusting the GDT means adjusting the CS register (which means a far return).

3 Likes

I appreciate your understanding. I’ve already commented on an issue about Inline Assembly, however, and offered a solution (something like a DSL, where assembly instructions look like normal functions, but are translated into assembly instructions instead of function calls. But I ran into a problem when fleshing it out involving AVX-512 stuff in regards to mask registers, broadcasting, etc., and constraints.

1 Like