Because you only have four general purpose registers? Registers=super fast, memory=super slow (a read from non-cached memory can take several cycles, which your code will have to wait on.) You want to use registers as often as possible, preferably in any one code block read directly from a memory location once and write once. And stack based processors would generally be optimised for using the stack as opposed to doing memory transactions all the time. So, you push and pop constantly.
I wouldn't pretend to be all knowing about x86 assembler, but there's typically much more going on than there should be because it's all based on 1980s technology. This is pretty much what I know of it, so some might have changed a fair bit now we're using pseudo-x86 modern processors on multi-tasking environments.
To write really quick code you need to have a very clever compiler that manages the registers and the stack well. You also need to consider that the code you generate will typically be very generic. You may end up writing a function that uses the stack even though it doesn't always have to, simply because it MIGHT have to. It's far more complicated than just writing the basic code straight into its assembly equivalents. Then you have to consider what asm the processor itself will optimise. A missed branch prediction on a PIV CPU will have to empty the whole pipeline, which I guess means you'd want to limit the amount of branching you do.
I could probably mock up some pseudo assembly to show you what I mean, but google x86 asm and you'll probably find some perfect examples of ugliness. Having a basic understanding of asm can help you write better higher-level code too.
I wouldn't pretend to be all knowing about x86 assembler, but there's typically much more going on than there should be because it's all based on 1980s technology. This is pretty much what I know of it, so some might have changed a fair bit now we're using pseudo-x86 modern processors on multi-tasking environments.
To write really quick code you need to have a very clever compiler that manages the registers and the stack well. You also need to consider that the code you generate will typically be very generic. You may end up writing a function that uses the stack even though it doesn't always have to, simply because it MIGHT have to. It's far more complicated than just writing the basic code straight into its assembly equivalents. Then you have to consider what asm the processor itself will optimise. A missed branch prediction on a PIV CPU will have to empty the whole pipeline, which I guess means you'd want to limit the amount of branching you do.
I could probably mock up some pseudo assembly to show you what I mean, but google x86 asm and you'll probably find some perfect examples of ugliness. Having a basic understanding of asm can help you write better higher-level code too.