How do I get the current value of the RSP register from a C/C++ function? (No answer, but a solution.)


A customer using Visual Studio wanted to know how to obtain the current value of the x64 RSP register from a C/C++ function. They noted that on the x86, you can drop to inline assembly, and on the ia64, you can use the __getReg intrinsic to retrieve the value of any register. There is no corresponding __getReg intrinsic on x64.

There's no really good way of doing this. The customer can sort of get close with _Address­Of­Return­Address(). Other approximations would be to call _alloca(0), or to call a helper function which allocates a local variable and returns its address.

Now, if you were the one answering this question and you stopped there, then you'd be guilty of answering the question without first understanding the problem. There must be some larger problem they are trying to solve, and they managed to break it down into two parts, the easy part and the impossible part, and they wanted help with the impossible part.

The customer was kind enough to elaborate.

"We are using RSP to generate a system-wide unique value."

Whoa, there. RSP is not all that unique. After all, if the function gets called twice, the RSP value might be the same the second time. (Maybe they clean up the unique value when the function returns, so this isn't a problem.) And of course, since each process has its own address space, another process can perform the same operation with the same value of RSP.

If you want a system-wide unique 64-bit value, use the function Allocate­Locally­Unique­Id.

Comments (14)
  1. Jonny says:

    Although you cannot do inline assembly with the x64 compiler  you can include an assembly file in your project.

    PROC GetRSP

    push rsp

    pop rax

    return

    GetRSP ENDP

    [This code is not valid according to the Win32 ABI. If the "push rsp" takes a stack overflow, your process will be terminated due to missing unwind data. In fact, it will probably be flagged as potential malware code injection. On top of that, it doesn't even answer the question (much less solve the problem), since this does not return the original rsp but rather the GetRSP function's rsp! -Raymond]
  2. Joshua says:

    I saw a constrained version of this solution in the nethack source code. The constrained version ended up being process-wide unique while allocated. The solution was an otherwise unused local variable on the stack that had its address taken.

    @Jonny: nice.

  3. Joshua says:

    [This code is not valid according to the Win32 ABI. If the "push rsp" takes a stack overflow, your process will be terminated due to missing unwind data.]

    Can't happen. The call instruction that called this function left the stack at an odd multiple of 8.

    [Good point. It's still not a habit you should fall into, though, since most functions are not this trivial. -Raymond]
  4. Don says:

    Is there doc page for Allocate­Locally­Unique­Id? Couldn't find one on MSDN. The Google has a couple of links to undocumented APIs but was hoping to read a bit in something official

  5. @Don says:

    It was the first Google Result for me? msdn.microsoft.com/…/aa375260%28v=vs.85%29.aspx

  6. Don says:

    Funny. I was using Bing (and of course the term Google to mean "searching the web" ;)) http://www.bing.com/search

    [Um, you searched for the soft hyphens. -Raymond]
  7. Mihai says:

    I first tried bing too. It showed some 3rd party links. Then I used the ye olde engine which linked me to msdn directly (prolly because I'm logged in and knows my preferences). The thing is, I've now tried bing again and the msdn link is first. How about that. :-)

  8. alegr1 says:

    @Joshua:

    Too bad that two consequential calls in the same context will return the same value.

  9. Don says:

    Looks like the search picked up the soft hyphens cause I copied and pasted from the article. Allocate & shy; Locally & shy; Unique & shy; Id   Html entities throwing me off! Thanks for the links above. Another good article Raymond. Never heard of that API which is what got me searching.

  10. Yuhong Bao says:

    "This code is not valid according to the Win32 ABI."

    *Windows x64 ABI.

  11. foo says:

    I was more interested in learning of the existence of _AddressOfReturnAddress. Googling it verbatim produced this as one of the results: stackoverflow.com/…/reading-the-rsp-register-from-microsoft-c (Reading the RSP register from Microsoft C++). That Jalf guy is pretty smart… he basically asked in a comment what Raymond asked.

  12. Myria says:

    @Jonny: Why not "mov rax, rsp" "ret"?  No need to use the stack, and such a function is valid as a leaf (the first instruction is 2 bytes).

    I've used the value of ESP/RSP as one of many parts of a seed for a secure random number generator in case CryptGenRandom and SystemFunction036 fail for some reason.  It does work a little bit, particularly with /DYNAMICBASE and on Windows 8 /HIGHENTROPYVA.

    Asking for the stack pointer is inherently inaccurate in C.  For example, in x86-32, Visual C++ generally will use "push" to put parameters to subroutines onto the stack.  If you were to pass the value of ESP to such a function, which ESP do you mean?

  13. David Walker says:

    The point of this story is that the user was looking for the wrong thing.  They wanted a system-wide unique value, but they were not looking in the right place to generate one.

Comments are closed.

Skip to main content