Shellcode is machine code that when executed spawns a shell, sometimes. Shellcode cannot have any null's in it because it is (usually) treated as a C string and a null will stop the reading of the string, as it is the string delimiter. Not all "shellcode" spawns a shell, this has become a more generic name for a bit of position independant machine readable code that can be directly executed by the cpu. Shellcode must always be position independant - you cannot access any values through static addresses, as these address will not be static in the program that is executing your shellcode - environment variables are the execption to this rule. Remember to always use the smallest part of a register possible to avoid null's, and xor is your friend.