A month or two ago I suggested that we should have a standard library function to get the value of the stack pointer, and also the frame pointer.

Another useful function for analysing and manipulating the stack would be as follows:

      void set_stack_pointer_and_invoke( char *custom_stack, void (*funcptr)(void) );

You would use this function to invoke another function with your own custom stack, for example:

    char *const mystack = new char[4096u];
    set_stack_pointer_and_invoke( mystack + 4088u, SomeLibraryFunction );

Since the stack grows negatively on x86_64, I add 4088 to it to give it the highest address for a 64-Bit value. Alternatively the function could take a third parameter to indicate the size of the stack and let the compiler decide how to calculate it. Here's one way of determining it:

bool stack_grows_positively_Detail(int *const p)
    return static_cast<uintptr_t>(p) < static_cast<uintptr_t>(&p);
}

bool stack_grows_positively(void)
{
    int i;
    return stack_grows_positively_Detail(&i);
}

This would serve two purposes:
(1) If you have a recursive function that will re-enter thousands of times, then you can temporarily allocate a stack in the gigabytes.
(2) If the stack isn't executable, and you need to execute the stack. Or, if the stack _is_executable, and you want to prevent execution of the stack (for added security when calling 3rd party library functions).

The x86_64 assembler for changing and later restoring the stack pointer is as follows:

set_stack_pointer_and_invoke:
    push r15 ; callee-saved
    mov r15,rsp ; save the original stack pointer
    mov rsp,rdi ; set the stack pointer
    call rsi ; invoke the function pointer
    mov rsp,r15 ; restore the original stack pointer
    pop r15 ; restore the original value of r15
    ret

I have this working for x86_64 up on GodBolt with support for exception handling:

https://godbolt.org/z/M9544Meqq