The Art of Assembly Language [pdf]
ic.unicamp.br
ic.unicamp.br
http://www.plantation-productions.com/Webster/www.artofasm.c...
Randall Hyde is a legendary educator, hacker and active member x86 assembly community.
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
The latest PCs can still run DOS (often needed for BIOS updates), so the programs will still assemble and run. There is indeed a 640K limit, but even the 64K limit of a basic single-segment .COM file will seem like a huge amount to work with if you're just starting out with Asm; a "Hello World" program is around two dozen bytes. (Learning Asm really changes your perspective on things like efficiency - I've taught it to programmers who have only ever used high-level languages, and they are often surprised at the vast differences in scale. Ditto when showing them some nice 4k/64k productions from the demoscene.)
Then once you learn the basics, it's not so hard to go up to 32, then 64 bits, and Windows/Linux environments.
Computer Systems: A Programmer's Perspective By Randal E. Bryant and David R. O'Hallaron
I've always had a great interest into reverse engineering, so I thought learning assembly from the ground up would be a good start. However, I've actually learned more about some general concepts on how the computers work on the lowest level than I did the actual assembly programming; probably due to me losing focus further I went into the book.
I've never really continued my journey into the reverse engineering in great depth, but I'm curious how much this book is relevant to the problems today that are solved with assembly language.
This would be a good foundation, though. Not everything has changed.
Busted though, reading this specifically to review for a final CS exam in hardware/OSes.
This book might pair nicely with a current Coursera (which, yes, I'm also using to review for the final): https://www.coursera.org/course/hwswinterface
Didn't realize how old this was until I hit that line
Also does anyone know if there is a solution manual available anywhere for this edition? Thank you!
This is a great find; looking forward to learning this stuff the right way.
I have been reading that very same book, but third edition, which focuses on GNU/Linux as platform, and it's way better.
Also, you can "find online" the pdf for the third edition.