This book is the first of a four-part series designed for programmers. This volume starts with the architectural basics, but includes plenty of C code examples to make it a worthwhile read for a new C developer. The book covers the typical range of topics from data representation to memory and interrupts.
The chapters tend to be specific enough to gain a general understanding of how things work, but it does not delve deep enough for someone that is going to be doing down and dirty embedded programming. This tends to show up in areas such as the discussion of instruction sets that I actually like. It defines an imaginary x86-compatible architecture that is essentially a subset of an actual x86 chip. It is not a bad approach because the full discussion of any of today's x86 chips, like the Athlon or Pentium 4, needs four volumes of its own. The chapter does take a look at the differences between a full x86 instruction set, but does not explore the details of each opcode. I would have also preferred to see more of a discussion of architectures such as the 8051, PIC, ARM, and Coldfire.
The only major problems I found were in the discussion of memory. Talking about garbage collection and not even mentioning Java seems a bit off. Likewise, the discussion of NUMA (non-uniform memory architecture) was very superficial and it could easily confuse a new programmer.
What I did like about this book is the plethora of options that are presented. For example, the character encoding section near the start of the book takes a look at the usual C zero terminated strings as well as more esoteric items like Delphi string encoding and Unicode support.
The book lays a good groundwork, although with a somewhat x86-centric view, that makes it worth having. It will be interesting to see how the the remaining three books address the actual job of programming now that the base has been cast.
If you're interested in writing software code, you might also like these books: