Below are some of the more common integer and logic operations.
Instruction | Effect | Description |
leaq S,D | D <– S | Load effective address |
Unary Classes | ||
inc D | D <– D+1 | Increment |
dec D | D <– D-1 | Decrement |
neg D | D <– -D | Negate |
not D | D <– ~D | Complement |
Arithmetic and Logic Classes | ||
add S,D | D <– D + S | Add |
sub S,D | D <– D – S | Subtract |
imul S,D | D <– D * S | Multiply |
xor S,D | D <– D ^ S | Exclusive OR |
or S,D | D <– D | S | logical OR |
and S, D | D <– D & S | logical AND |
Shift Classes | ||
sal k, D | D <– D << k | Left shift (fill with zeros) |
shl k, D | D <– D << k | Left shift (same as sal) |
sar k, D | D <– D >>A k | Arithmetic shift right (filled with most sig bit) |
shr k, D | D <– D >>L k | Logical shift right (zero filled) |
Note: Each unary, binary and shift operation has 4 variants for each size: b, w, d, q.
Load Effective Address
- leaq copies the value of S (not value at S) into D.
Examples
Suppose %rdx contains some value x.
leaq 7(%rdx, %rdx, 4), %rax // copies 5x + 7 into %rax
7(%rdx, %rdx, 4) = (7 + x + 4x) = 5x + 7
Suppose %rax holds x and %rcx holds y.
leaq 9(%rax, %rcx, 2), %rdx // copies 9 + x + 2y into %rdx
9(%rax, %rcx, 2) = 9 + x + 2y
leaq 0xA(,%rcx,4), %rdx // copies 10 + 4y into %rdx
0xA(,%rcx,4) = 10+4y
Unary Ops
- Operand serves as both source and destination
- Operand can be register or memory location
Arithmetic and Logic Classes
- The first operand can be an immediate value, register or memory location.
- The second argument can only be a register or memory location.
- They both can’t be memory locations
Shift Classes
- The first operand is the shift amount. Can be an immediate value or the single-byte register %cl. Note: %cl can store the values 0 – 255.
- The destination operand can be a register or memory address.
Example
long arith (long x, long y, long z) { long t1 = x ^ y; long t2 = z * 48; long t3 = t1 & 0x0F0F0F0F; long t4 = t2 - t3; return t4; }
Assembly code
Note: x is in %rsi, y is in %rdi, z is in %rdx
arith: xorq %rsi, %rdi // t1 = x ^ y leaq (%rdx, %rdx, 2), %rax // 3 * z salq $4, %rax // t2 = 16 * (3*z) = 48*z andl $252645135, %edi // t3 = t1 & 0x0F0F0F0F subq %rdi, %rax // return t2 - t3 ret
Special Arithmetic Operations
When multiplying two 64-bit integers, the product may require 128 bit to represent the result. The x86-64 instruction set provides limited support for operations involving 128-bit numbers.
Intel refers to a 16-byte quantity as an oct-word.
Instruction | Effect | Description |
imulq S | R[%rdx]:R[%rax] <– S x R[%rax] | Signed full multiply |
mulq S | R[%rdx]:R[%rax] <– S x R[%rax] | Unsinged full multiply |
cqto | R[%rdx]:R[%rax] <– SignExtend(R[%rax]) | Convert to oct-word |
idivq S | R[%rdx] <- R[%rdx]:R[%rax] mod S;
R[%rax] <- R[%rdx]:R[%rax] / S |
Signed divide |
divq S | R[%rdx] <- R[%rdx]:R[%rax] mod S;
R[%rax] <- R[%rdx]:R[%rax] / S |
Unsigned divide |
One-operand Multiply Instructions
- Both imult and mulq expect one argument to already be in %rax.
- %rdx holds the high order 64-bits
- %rax holds the low order 64-bits
Signed Extension to Oct-word: cqto
- takes no arguments
- reads the sign bit from %rax and copies it accross %rdx
- cqto is listed as cqo in the Intel documentation.
© 2017 – 2018, Eric. All rights reserved.