← Back to context

Comment by im3w1l

12 days ago

Never seen inline assembly written quite like that, is this actually correct code? I'm concerned that normally register annotation is just a hint, and that the assembly blocks are not marked volatile - and that the compiler may therefore be free to rewrite this code in many breaking ways.

Edit: Ah a basic asm blocks is implicitly volatile. I'm still a little concerned the compiler could get clever and decide the register variables are unused and optimize them out.

Tried it with GCC, and without any optimization it does print the message. With "-O2" however, we get this:

    Disassembly of section .text:
    
    0000000000001040 <main>:
        1040: 0f 05                 syscall 
        1042: 31 c0                 xor    %eax,%eax
        1044: c3                    retq   

Everything except the syscall instruction has been optimized away!

  • Now that's incredibly cursed. Could do basically anything and swallows the error too!

I think that named register variables (a GCC extension) are meant to be live in asm block by design, so they shouldn't be optimized away.

Still I would use extended asm.

edit: from the docs: "The only supported use for [Specifying Registers for Local Variables] is to specify registers for input and output operands when calling Extended asm".

So the example is UB.

  • It's not UB, it's documented behaviour of a vendor extension.

    It's not UB because it's defined as outside the scope of the language standard. The vendor (in this case, GCC) does document how to use its inline assembly extension in quite a lot of detail, including how to use clobber lists to prevent exactly the kind of thing these failures demonstrate.