3 ms·
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
by im3w1l 2y 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.
- rep_lodsb 2y agoTried 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!
- im3w1l 2y agoNow that's incredibly cursed. Could do basically anything and swallows the error too!
- gpderetta 2y agoI 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.
- bregma 2y agoIt'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.
- gpderetta 2y agoGCC says that register extensions are not supported with basic asm. What happens if you do it anyway is not documented. Ergo UB.
- bregma 2y agoGCC says that register extensions are not supported with basic inline asm. If you do it anyway it doesn't work it's not undefined behaviour, it's behaving as documented. Once you've ventured into vendorland you're outside the realm of undefined behaviour to start with, but following the vendor's documentation on how to use the vendor's extension is the minimum requirement for meeting your expectations that the feature will work.
- gpderetta 2y ago> it's behaving as documented. what do you think the documented behaviour is? None is documented, so it is undefined. The only defined behaviour is with extended asm. Remember in C and C++ everything is UB unless defined in the standard or by an implementation. If it was documented as giving an hard error, you would be right. But it is not.
- im3w1l 2y agoI don't think this is exactly correct. Undefined behavior means a very specific thing - that the program could do literally anything. But I think that's not quite the situation in this case. Rather, I would suspect that these specified-register variables are only guaranteed to be effective with extended asm constraints. For basic asm I would assume then that the register contents cannot be relied on to contain the value of the variable, but as long as you don't rely on it, then you are in the clear. Then again it's hard to be sure about these matters with C.
- gpderetta 2y ago> For basic asm I would assume then that the register contents cannot be relied on to contain the value of the variable, but as long as you don't rely on it, then you are in the clear. That's the crux. The example invokes 'syscall', which obviously relies on specific register content, from basic asm.