Question

I was told if I use rsp as a general purpose register the operating system may dump registers to where it points in the case of an interrupt, causing problematic behavior.

Is this true, and if not hence, if I don't need a stack, could I use rsp as a general purpose register?

Edit: Running in user space.

Was it helpful?

Solution

Aren't you screwed if an interrupt occurs?

Those of you who have programmed in DOS are likely squirming at this point about the possibility of interrupts. Ordinarily, reusing the stack pointer like this is a really bad idea because you have no idea when an interrupt might strike, and when one does, the CPU dutifully pushes the current program counter and flags onto the stack. If you have reused ESP, this would cause random data structures to be trashed. In this kind of environment, ESP must always point to valid and sufficient stack space to service an interrupt, and whenever this does not hold, interrupts must be disabled. Running with interrupts disabled for a long time lowers system responsiveness (lost interrupts and bad latency), and isn't practical for a big routine.

However, we're running in protected mode here.

When running in user space in Win32, interrupts do not push onto the user stack, but onto a kernel stack instead. If you think about it, it isn't possible for the user stack to be used. If the thread were out of stack space, or even just had an invalid stack, when the CPU tried to push EIP and EFLAGS, it would page fault, and you can't page fault in an interrupt handler. Thus, the scheduler can do any number of context switches while a no-stack routine is running, and any data structures that are being pointed to be ESP will not be affected.

From http://www.virtualdub.org/blog/pivot/entry.php?id=85

OTHER TIPS

Yes you could under very controlled circumstances, but in practice just use SSE2 and/or MMX instead.


Related: Is it valid to write below ESP? discusses things in Windows that can asynchronously use the stack pointer in 32-bit code. With an invalid stack pointer, those things would crash instead of stepping on space below it. (Or if pointing to writeable memory, use that as stack space.)

In GNU/Linux, signal handlers can asynchronously use the user-space stack pointer, but you can use sigaltstack / SA_ONSTACK to use an alternate stack for them.


Also note that x86-64 guarantees SSE2. You usually only need to consider using RSP as a 16th general-purpose register if you've already used all of xmm0..15 (SSE) and mm0..7 (MMX).

Using ESP as an 8th general-purpose register in 32-bit DSP code for CPUs without MMX made sense sometimes; that's why discussion about it can be found in the context of virtualdub filters.

It generally doesn't make sense in 64-bit code because you always have 16x 128-bit SIMD registers (and SIMD instructions to use on them), as well as more than twice as many non-stack-pointer integer registers. And 8x 64-bit mmx registers, or 8x 80-bit x87 registers, however you want to use them. In most calling conventions, most of these registers are call-clobbered, but you couldn't make function calls with RSP not pointing into the stack anyway.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top