Your question should be: is the frame pointer redundant?
In most cases, code can only be written using the stack pointer and not use the pointer on most processors (some processors, such as x86 in 16-bit mode, have restrictions on access to the stack pointer, so a frame pointer is required).
One example:
mov ebp, esp push esi mov eax, [ebp+4] push edi mov eax, [ebp+8]
can also be written as:
push esi mov eax, [esp+8] push edi mov eax, [esp+16]
Some special cases, such as the alloca () function, however require the use of both frame and stack pointers.
The stack pointer is never redundant:
You must consider that the stack pointer is used by interrupts. Interrupts are functions of the operating system that are automatically called by the hardware (instead of the CALL instruction) when certain conditions are met (for example, an electrical signal is received from a USB port).
Since such interrupts suggest that memory below the stack pointer is free, it would be a very bad idea to use memory under the stack pointer; if an interrupt occurs, than the memory below the stack pointer will be destroyed!
In MIPS processors (for example), this is a pure convention, which of the registers is a stack pointer; you can also say that R9 is the stack pointer, and the stack is not at address R9, but at address R9 + 1234. The 64-bit Sparc calling convention uses such a strange convention for the stack pointer. However, this requires that all code (including the operating system and all interrupts) use the same convention.
On x86 processors, this is impossible, because the processor itself will consider that the memory below the stack pointer is free: PUSH and CALL instructions will be written to memory under the stack pointer, and in case of interruption, the processor will store information at the address pointed to by the stack pointer, without the ability to change this behavior!