int bar(int a, int b) { int z = a * b; foo(); return z; }
Where to put `z`? It has to be someplace where `foo` won't clobber it, like a callee-saved register - in this case ebx.
But now `bar` is responsible for saving the value of ebx for its caller. That explains the push and pop.
Alignment is unrelated; this is just about calling conventions.