Actually, before you worry about the other resources in this comment - start with _Let's Build a Compiler_ (http://compilers.iecc.com/crenshaw/) - it'll make compilers seem much less intimidating. Follow along in Python, Ruby, Lua, whatever.
I'm Not A Fan of the old Dragon book. I haven't read the new one or _Engineering a Compiler_ (yet), though.
I highly recommend _Essentials of Programming Languages_, though it focuses on interpreters rather than compilers. There's a chapter at the end of the first printing (they cut it from the second and third editions, le sigh) about taking a CPS-based interpreter and turning it into a compiler, too. Very cool.
Also, since you seem to have the same quirky, self-taught background I do - I found tinkering with low-level implementations of Forth to be very helpful in understanding virtual machines. Read the source to jonesforth (http://www.annexia.org/forth) and/or write a Forth in C, it will teach you quite a bit. Also, read about Lua's virtual machine - it's small, clean, and very well engineered.
:) That is actually what I did last month. (The assembler source doesn't always translate well to C, so it required a lot of careful thinking about what is going on and how to expres it in C.) I think I ended up writing three Forths, and I did indeed learn a lot.
I did some of the other things too... used to have LiSP, worked through the first few chapters of EOPL, did the Crenshaw tutorial too back in the day.
I still feel that the way I do things are, well, hackish, and incomplete, and suboptimal. I was kind of hoping that there would be a Book that would solve these problems...