|
I think you're too quick to dismiss the value of older texts. I first "got" assembly language from reading the infamous 6502.txt, which was probably somewhere between 10 and 20 years old at that point, and written about a totally obsolete (but still in widespread use to this day, believe it or not) 8-bit CPU. It didn't matter, learning about instructions and opcodes and memory maps and addressing modes was universally important. Likewise, when I wanted to learn x86 assembly somewhat recently, the texts I learned the most from were written in the Windows 95 era, when the transition from 16 to 32 bit and DOS to Windows was underway. It didn't hamper me at all, because while microarchitectures have changed considerably (and thus most optimization tips would be useless), the instruction set architecture has not been "broken," only added to. If you really want to "get" x86-64, you need to know how it evolved from 32 bit x86, and 16 bit x86 before that. I think the older texts are actually superior for this purpose, because newer ones are missing a lot of historical context. A 64 bit-focused guide may tell you that accessing 16 bit values can be bad for performance, because any instructions on 16 bit values in memory need an extra prefix byte, and leave it at that. Maybe they won't even bother telling you that, and work only at the assembly language level, since that's all that matters for debugging compiler-produced code. An older guide, from when DOS was still relevant, gives much more context: The x86 architecture was originally 16 bit, and a bit in the most common instruction opcodes indicated whether to operate on an 8 bit or 16 bit value. When expanding the architecture to 32 bits, the designers realized that 16 bit values would be needed much less often than 8 or 32 bit ones, and redefined that bit to select between 8 and 32 bit data sizes. A data size prefix byte was added to the architecture to give 32 bit code the option of operating on 16 bit values at the expense of an extra instruction byte (and giving 16 bit code the option of using 32 bit data, actually). That information is a lot more likely to stick in your head if you know the reason for it instead of just saying "here's another quirk of this crusty, weird architecture. How baroque it is." Another reason to prefer older texts is that assembly language was relevant to a much wider range of programmers then, when processors were slower, compilers less advanced, and games and demos made around tight assembly routines, so there's more written about DOS and Win32 assembly than will probably ever be about x86-64. That said, don't waste too much time on BCD, segments, and near/far pointers ;) EDIT: Here are some random resources I found valuable: Understanding Intel Instruction Sizes: http://www.swansontec.com/sintel.html (explains 16 and 32 bit x86 instruction encoding. I submitted it here: https://news.ycombinator.com/item?id=7996806) The Art of Picking Intel Registers: http://www.swansontec.com/sregisters.html (explains the original intended purpose of the various x86 registers. While you can ignore them and use most registers pretty much interchangeably in 32 and 64 bit x86, there are shorter encodings and special operations that can only be done with certain registers) Agner Fog's software optimization resources: http://www.agner.org/optimize/ (extremely detailed manuals on modern x86 microarchitectures and optimizing code in C++ and assembly for them) x86 Calling Conventions, C programmer's view: http://www.unixwiz.net/techtips/win32-callconv.html and assembly language programmer's view: http://www.unixwiz.net/techtips/win32-callconv-asm.html |
I wonder how much of this applies to programming e.g. an arduino board