esp is the stack pointer, ebp is/was for a stack frame so that when you entered a function ebp could get a copy of esp at that point, everything on the stack before that happens, return address, passed in parameters, etc and things that are global for that function (local variables) will now be a static distance away from the stack frame pointer for the duration of the function. esp is now free to wander about as the compiler desires and can be used when nesting to other functions (each needs to preserve the ebp naturally).
it is a lazy way to manage the stack. makes compiler debugging a lot easier, makes understanding the code generated by the compiler easier, but burns a register that might have been otherwise general purpose.