6

Consider inline assembly like this:

uint64_t flags;
asm ("pushf\n\tpop %0" : "=rm"(flags) : : /* ??? */);

Nonwithstanding the fact that there is probably some kind of intrinsic to get the contents of RFLAGS, how do I indicate to the compiler that my inline assembly clobbers one quadword of memory at the top of stack?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
fuz
  • 88,405
  • 25
  • 200
  • 352
  • 3
    AFAIK, you can't. I *think* the only safe way to write this is by modifying rsp around the pushf/pop so you don't step on the red zone. (Use `add -128` / `sub -128` so they can use an imm8 encoding). And then of course the output constraint has to be `"=r"`, because a memory operand could use an rsp-relative addressing mode. Avoiding the red-zone is the best anyone's been able to come up with in discussions of the same issue on previous SO questions. – Peter Cordes Aug 26 '16 at 07:22
  • You could also save/restore `[rsp-8]` into a register, but that seems worse than modifying rsp, even if it makes the stack engine insert an extra uop. – Peter Cordes Aug 26 '16 at 07:25
  • 1
    There is no way to tell extended asm that you are clobbering the stack. That said, what exactly are you trying to accomplish? There might be some other tricks that do what you need (maybe lahf?). – David Wohlferd Aug 26 '16 at 07:40
  • Oh and yeah, there is an intrinsic: `__readeflags()` (and yes, it works on x64). – David Wohlferd Aug 26 '16 at 07:55
  • 1
    @DavidWohlferd I was thinking about how inline assembly that clobbers part of the stack would work and this is a good example for motivation as `pushf` is the only way to get the entire RFLAGS register. – fuz Aug 26 '16 at 08:30
  • @DavidWohlferd Interestingly, the [intrinsics](https://gcc.gnu.org/ml/gcc-patches/2013-12/msg00386.html) don't seem to address this issue either. – fuz Aug 26 '16 at 08:48
  • Ah, I see, that was the first stab, it seems like they reimplemented that as a builtin afterwards. – fuz Aug 26 '16 at 08:51
  • 1
    related: you can't tell gcc that you want to clobber the *whole* red zone either (except by compiling the whole file or function with `-mno-red-zone`). So to make a function call in inline-asm, you have to jump through hoops: See http://stackoverflow.com/questions/37502841/calling-printf-in-extended-inline-asm and http://stackoverflow.com/questions/37639993/is-this-assembly-function-call-safe-complete. (Calling functions from inline asm is just a bad idea, but people trying to learn asm using inline-asm keep wanting to do it.) – Peter Cordes Aug 26 '16 at 09:49

1 Answers1

1

As far as I am concerned, this is currently not possible.

fuz
  • 88,405
  • 25
  • 200
  • 352
  • One workaround is to do something like `add $-128, %rsp` before using the stack, to skip past the red-zone, and `sub $-128, %rsp` after. (`-128` fits in an imm8 so it's smaller than sub $128). TODO: link an existing Q&A. – Peter Cordes Dec 21 '20 at 00:13
  • [Calling printf in extended inline ASM](https://stackoverflow.com/a/37503773) shows an example of skipping the red-zone before using the stack in inline asm. (And the inconvenience of declaring clobbers on all the call-clobbered registers, if you're going to call an arbitrary function!) – Peter Cordes Jul 20 '22 at 18:05