图3.10列出了一些x86-64整数以及算术运算。
Most of the operations are given as instruction classes, as they can have different variants with
different operand sizes. (Only leaq has no other size variants.) For example, the instruction class add consists of four addition instructions: addb, addw, addl, and addq, adding bytes, words, double words, and quad words, respectively.
The operations are divided into four groups: load effective address, unary, binary, and shifts. Binary operations have two operands, while unary operations have one operand.
1 Load Effective Address
load effective address 指令leaq
实际上是movq指令的变种。It has the form of an instruction that reads from memory to a register, but it does not reference memory at all. 它的第一个操作数appears to be a memory reference, but instead of从指定位置进行读取,这个指令将effective address拷贝到destination中。We indicate this computation in Figure 3.10 using the C address operator &S. This instruction can be used to generate pointers for later memory references. In addition, it can be used to compactly describe common arithmetic operations. For example, if register %rdx contains value x, then the instruction leaq 7(%rdx,%rdx,4), %rax will set register %rax to 5x + 7. Compilers often find clever uses of leaq that have nothing to do with effective address computations. The destination operand必须是一个寄存器。
As an illustration of the use of leaq in compiled code, consider the following C program:
long scale(long x, long y, long z) {
long t = x + 4 * y + 12 * z;
return t;
}
When compiled, the arithmetic operations of the function are implemented by a sequence of three leaq functions, as is documented by the comments on the right-hand side:
The ability of the leaq instruction to perform addition and limited forms of multiplication proves useful when compiling simple arithmetic expressions such as this example。
2 Unary and Binary Operations
Operations in the second group are unary operations, with the single operand serving as both source and destination. 操作数可以是寄存器或内存地址。 For example, the instruction incq (%rsp) causes the 8-byte element on the top of the stack to be incremented. This syntax is reminiscent of the C increment (++) and decrement (–) operators.
The third group consists of binary operations, where the second operand
is used as both a source and a destination. This syntax is reminiscent of the C
assignment operators, such as x -= y. Observe, however, that the source operand
is given first and the destination second. This looks peculiar for noncommutative
operations. For example, the instruction subq %rax,%rdx decrements register
%rdx by the value in %rax. (It helps to read the instruction as “Subtract %rax from
%rdx.”) The first operand can be either an immediate value, a register, or a memory
location. The second can be either a register or a memory location. As with the
mov instructions, the two operands cannot both be memory locations. Note that
when the second operand is a memory location, the processor must read the value
from memory, perform the operation, and then write the result back to memory.
待补充 222