The first book I read about Intel Assembly was lacking information about 64 bits programming. So I ordered and read Introduction to 64 Bit Intel Assembly Language Programming for Linux, by Ray Seyfarth.
This book covers a lot of subjects in assembly. It is adapted to people starting assembly, but it also contains advanced assembly programming techniques. I think that this book is adapted to a lot of people wanting to improve their skills in Intel Assembly. This book covers only 64 bit Intel Assembly in details. It does not cover old memory models, only the memory mode used now.
This book uses yasm to assemble the programs. It uses gdb to debug the assembly programs.
The first chapters are very general. They are covering numbers (octal, decimal and hexadecimal notions), computer memory and memory mapping mode.
The first technical chapter covers Registers in details. It defines all the registers available in Intel Assembly. You will see how to move constants to registers. You will also learn how to move values between memory and registers. Then, the next chapter covers all the mathematical operations (negate, addition, subtraction, division and multiplication). It also covers the use of conditional move instructions. The next one is about bit manipulations (not, and, or and shift). It also covers bit testing and filling.
After that, the chapter eight covers a very important subject: branching and looping. All the jumps are covered in details. You will see how to convert each control structure (if, for, while, do-while) of programming language to assembly. After that, the string instructions are also explained. Once you know how to create control structures, it's time to create your own functions. In that chapter, you will learn the stack and the function call conventions. The stack frames and the recursion are also covered.
The arrays are covered in the next chapter. You will see how to allocate arrays on the stack or on the heap using malloc. The command line parameters are also covered (that was a very interesting part).
Then, floating point math is covered. For that, the Streaming SIMD Extensions (SSE) are used. All the math operations are covered. As is the way to transfer data between XMM registers and memory. The conversion and comparison instructions are also explained here. Some complete samples like dot product of 3D vectors help us understand the SSE instructions.
The system calls are covered in details in chapter twelve. The C system library wrapper functions for system calls are also covered. After that, a whole chapter addresses structures. The allocation of structs is also addressed. Then, the way to use I/O streams from assembly is taught.
A whole chapter is devoted to the implementation of data structures in Intel Assembly. The covered data structures are the linked lists, doubly linked lists, the hash tables and the binary trees. Each common operation on these data structures is implemented.
After that, the last chapters are about optimization and performances. The chapter 16 covers High Performance Assembly Programming in details. In that chapter, you will learn a set of optimization that can be applied to improve the performances of a given code. For example, you will see how to make efficient use of cache or how to make better performing loops. These optimization can also be applied to other programming languages. The following chapters are all covering a single problem and a way to optimize it the most using Intel Assembly. For each of these problems, the C version is compared to the assembly version. Three problems are presented: counting bits in an array of integers, the Sobel filter and computing the correlation of two variables given some sample values.
To conclude, I found this book very book. It covers a lot of subjects in a very good manner. I liked a lot the performance techniques covered in the book. The deep coverage of SSE instructions was also very interesting.