Inline assembly compilation error in simple function for modifying const local variable

I’m exploring inline assembly in Zig, but I have a compiler error.

I’m using Zig version 0.15.2

The goal is to create a swap function without creating a temporary variable like this:

fn swap(x: *u32, y: *u32) void {
    x.* ^= y.*;
    y.* ^= x.*;
    x.* ^= y.*;
}

I tried writing this, but in assembly for educational purposes. I’m not certain that the logic is correct, because I haven’t tested it. It does not compile.

fn swap32(x: *u32, y: *u32) void {
    asm volatile (
        \\ xord     %[eax], %[ebx]
        \\ xord     %[ebx], %[eax]
        \\ movd     %[eax], %[x]
        \\ xord     %[eax], %[ebx]
        \\ movd     %[ebx], %[y]
        : [x] "{eax}" (x),
          [y] "{ebx}" (y),
    );
}

The documentation on inline assembly is sparse, so I’ll just say what I’m trying to do. I’m trying to load x into eax and y into ebx. Then, the operations are pretty clear. The error I get is this:

~/software/MISC/zig/generic_swap > zig build-exe generic_swap.zig
generic_swap.zig:20:5: error: asm cannot output to const local 'x'
    asm volatile (
    ^~~

So, I’m thinking something is really wrong with what I’m doing. Any insights?

You are asking it to write to a constant, ofc that is not allowed.

The syntax is asm : outputs : inputs : clobbers, I think you just forgot the outputs go fist. Since there are no outputs you can leave it empty, but you do need a second : to start the input list.

2 Likes

I see. It’s helpful seeing the syntax laid out like that, because I didn’t understand that before from the documentation. So I can’t say I forgot what I never knew lol. Thank you!

It is still not compiling though. First, it was saying invalid mnemonic for xord so I assumed that the syntax does not use AT&T syntax exactly with instruction suffixes (suffices?). I removed them all and just use mov and xor. Then it says:

generic_swap.zig:19:1: error: no matching constraint: '%[eax]'
fn swap32(x: *u32, y: *u32) void {

I read the documentation from here. That’s such a specific example and I’m genuinely mostly lost about the syntax. Is there any other documentation I can read to understand this? Should I try to understand the source-code itself?