While compilers for high-level programming languages are large complex software systems, they have particular characteristics that differentiate them from other software systems. Their functionality is almost completely well-defined - ideally there exist complete precise descriptions of the source and target languages. Additional descriptions of the interfaces to the operating system, programming system and programming environment, and to other compilers and libraries are often available.The final stage of a compiler is generating efficient code for the target microprocessor. The applied techniques are different from usual compiler optimizations because code generation has to take into account the resource constraints of the processor - it has a limited number of registers, functional units, instruction decoders, and so on. The efficiency of the generated code significantly depends on the algorithms used to map the program to the processor, however these algorithms themselves depend not only on the target processor but also on several design decisions in the compiler itself - e.g., the program representation used in machine-independent optimization. In this book, the authors discuss classical code generation approaches that are well suited to existing compiler infrastructures, and they also present new algorithms based on state-of-the-art program representations as used in modern compilers and virtual machines using just-in-time compilation. This book is intended for students of computer science. The book is supported throughout with examples, exercises and program fragments.