As the stack pointer may change while a function is executed, access to the stack is less confusing with a static frame pointer, that is set upon the entry to the function, so relative addressing becomes simpler.
On reason for using the stack to store parameters is that there is usually more memory available than registers. What would you do with a function g(a,b,c,d,e,f) where you have enough registers free to store a–e, but non for f? You would put f on the stack. As the size of the stack is only limited by the available memory using the stack still works for functions with even more parameters.
Modern compilers typically have a flag that controls whether the use of registers for parameter passing is allowed or not.