Data execution prevention is one of the earliest techniques that was introduced to provide protection against exploits and shellcode. The idea behind it is to stop the execution inside any memory page that doesn't have EXECUTE permission. This technique can be supported by hardware that raises an exception once shellcode gets executed in the stack or in the heap (or any place in memory that doesn't have this permission).
This technology didn't completely stop the attackers from executing their payload and taking advantage of memory corruption vulnerabilities. They invented a new technique to bypass DEP or NX called Return-oriented Programming (ROP) for this purpose.