Arithmetic and Logical Operations
Load Effective Address
- The instruction leaq is actually a variant of the
movq
instruction (from memory - register). But the difference is:movq
is used for moving the actual data. It copies the value from the source operand to the destination operand.leaq
is used for calculating effective addresses. It computes the address specified by the source operand and stores it in the destination operand.
- Example:
- Example 2: suppose register
%rbx
holds valuep
and%rdx
holds valueq
.
Instruction | Result |
---|---|
leaq 9(%rdx), %rax | 9+q |
leaq (%rdx, %rbx), %rax | p+q |
leaq (%rdx, %rbx, 3), %rax | 3p+q |
leaq 2(%rbx, %rbx, 7), %rax | 8p+2 |
leaq 0xE(,%rdx,3), %rax | 3q+14 |
leaq 6(%rbx,%rdx, 7), %rax | 7q+p+6 |
- Real-world usage illustration: consider the following program
- When compiled, the arithmetic operations of the function are implemented by a sequence of 3
leaq
functions:
- When compiled, the arithmetic operations of the function are implemented by a sequence of 3
Unary and Binary Operations
- First operand: can be an immediate, a register or a memory location
- Second operand: can be a register, or a memory location.
Example: subq %rax, %rdx
- “Subtract %rax from %rdx”
-
Registers contains these addresses:
Register Value %rax 0x100 %rcx 0x1 %rdx 0x3 -
These address contains these hex value:
Address Value 0x100 0xFF 0x104 0xAB 0x110 0x13 0x118 0x11 -
The following table shows the effects of the instructions:
Instruction Destination Value addq %rcx, %(rax) 0x100 0x100 subq %rdx, 8(%rax) 0x108 0xA8 imulq $16, (%rax, %rdx, 8) 0x118 0x110 incq 16(%rax) 0x110 0x14 decq %rcx %rcx 0x0 subq %rdx, %rax %rax 0xFD
Shift operations
- The shift amount either as an immediate value or with the single-byte register
%cl
. This 8-bit register can represent 0 -> 255.
In x86-64 assembly language, the shift instructions (salb, salw, sall, salq) all use the %cl register as the source of the shift count. The size of the data being shifted determines the effective shift count, and it is not directly related to the value in %cl.
- salb: Shifts a byte (8 bits) left by the value in the low-order 3 bits of %cl.
- salw: Shifts a word (16 bits) left by the value in the low-order 4 bits of %cl.
- sall: Shifts a long (32 bits) left by the value in the low-order 5 bits of %cl.
- salq: Shifts a quad-word (64 bits) left by the value in the low-order 6 bits of %cl.
So, if %cl has a hexadecimal value of 0xFF (binary: 11111111), the effective shift counts would be:
- For
salb
: 7 (since %cl is 8 bits, but only the low-order 3 bits are considered). - For
salw
: 15 (considering the low-order 4 bits). - For
sall
: 31 (considering the low-order 5 bits). - For
salq
: 63 (considering the low-order 6 bits).
Example 2: generate assembly code for the following C function:
- Generated assembly code: