ASM Intel syntax doesn't support %[ret]?

It’s me with dumb questions again.

So, I was working on porting some of my tooling from Rust and I was trying to get the PEB (Process Environment Block) with asm:

pub fn get_peb() *PEB {
    return asm volatile (
        \\ .intel_syntax noprefix
        \\ mov %[ret], gs:[0x60]
        : [ret] "=r" (-> *PEB),
    );
}

This is the error I get.

error: <inline asm>:2:6: unknown token in expression
 mov %rax, gs:[0x60]
     ^

Eventually, I managed to get around it by simply pointing it directly to rax:

\\ mov rax, gs:[0x60]

Although, I was curious what am I doing wrong in the first one?

I’m not 100% sure, but it might be a bug with Intel syntax handling in LLVM. It seems to expand %[ret] into %rax instead of rax, causing the error.

The docs say this about Intel syntax:

For x86 and x86_64 targets, the syntax is AT&T syntax, rather than the more popular Intel syntax. This is due to technical constraints; assembly parsing is provided by LLVM and its support for Intel syntax is buggy and not well tested.

1 Like

I got curious and dove into it a bit. I have to say I’m not knowledgeable about x86 assembly, I’ve only been doing a bit of ARM so far, but I came up with this in (hopefully correct) AT&T syntax:

export fn get_peb() *PEB {
    return asm volatile (
        \\ mov %gs:0x60, %[ret]
        : [ret] "=r" (-> *PEB),
    );
}

which seems to disassemble (with objdump on Linux) into

mov    %gs:0x60,%rax

When I test your workaround in Intel syntax, it disassembles (again with objdump on Linux) into the same thing, so I am fairly confident it’s correct.

1 Like

Yeah, you are right, checked the docu too now, it looks like it’s a bug with the intel flavor. Tx a lot!

For now I just hardcoded rax, but when I will need to perform wider operations with asm, I will do AT&T.

Tx a lot for this!