ALU Operations
ALU is a "Arithmetic Logic Unit". It is a hardware component within the CPU that does computations on data values.
- Computations include addition/subtraction and logical operations (shifts, bitwise, and, or, negation, etc).
- Typically, ALU only operates on integers. The CPU will have floating-point unit(s) for operations for FP values.
Load Effective Address
lea stands for "Load Effective Address."
Instructions that allow a memory reference as an operand generally does a address computation.
- E.g.,
movl 12(%rdx, %rsi, 4), %eax. The computed address (for source memory location) is%rdx+(%rsi x 4) + 12- 12 is the offset
%rdx%is the base%rsiis the index- 4 is the scaling
The lea instruction would compute a memory address, but does not access a memory location.
- E.g., leaq 12(%rdx, %rsi, 4), %rdi will update the address of %rdi
- keep in mind we're not obligated to use the coputer address as an address, we can just use it as an integer.
- lea does not set condition codes (e.g., on overflow)
In general, lea can do integer computations of the form where is 0, 1, 2, 4, or 8. if leaq r(p, q, S), <reg>
Example:
/* leaq_example.S */
.section .rodata
sFmt: .string "Result is: %lu\n"
.section .text
.globl main
main:
subq $8, %rsp
movl $0, %eax
movq $sFmt, %rdi
movq $1000, %r10
movq $3, %r11
leaq 15(%r10,%r11,8), %rsi
call printf
addq $8, %rsp
ret
- puts
1000intor10and3intor11leaq 15(%r10,%r11,8), %rsiputs1000+3*8+15into%rsi(the second argument).
Addition and Subtraction
add and sub instructions add and subtract integer values.
- Two operands, second operand is modified to store the result. Note: either operand (but not both) could be a memory refernece.
- Overflow is possible, and you can detect it using condition code.
Example:
movq $1, %r9
movq $2, %r10
addq %r9, %r10
/* %r10 now contains the value 3 */
subq %r9, %r10 means to subtract r9 from r10 and store it into r10
Asking for input
/* addsub.S */
.section .rodata
sPrompt: .string "Enter an integer value: " sInputFmt: .string "%u"
sFmt: .string "Result is %u\n"
- referring to labels without the
$refers to the content, while the$refers to the address.
.section .data
val: .space 4
.section .datadefines a section to store global variables. (we don't know how to put it on the stack yet)val: .space 4defines a variable and allocates 4 bytes.
Increment and Decrement
inc and dec instructions increment or decrement by 1. One operand, can be either register or memory
- Overflow is possible, check condition codes
Examples:
incq %rax /* increment %rax */
incl 4(%rbp) /* increment 32 bit value at addr %rbp+4 */
decq %rdi /* decrement %rdi */
Shifts
Left shift: shl
- shift one position to the left is the same as multiplying by two
Right shift: shr (logical: shfits in zeros) and sar (arithmetic: shifts in the value of the sign bit)
- shift one position to the right is the same as dividing by two.
Example:
movl $0xFFFF0000, %esi
shll $1, %esi /* %esi set to 0xFFFE0000 */
movl $0xFFFF0000, %esi
sarl $1, %esi /* %esi set to 0xFFFF8000 */
movl $0xFFFF0000, %esi
shrl $1, %esi /* %esi set to 0x7FFF8000 */
Bitwise Logical Operations
Two-operand logical operations: and, or, xor
Unary logical operations: not
Examples:
/* Note: 0x30 = 00110000b,
0x50 = 01010000b */
movb $0x30, %al; movb $0x50, %bl
andb %bl, %al /* set %al=0x10 (00010000b) */
movb $0x30, %al; movb $0x50, %bl
orb %bl, %al /* set %al=0x70 (01110000b) */
movb $0x30, %al; movb $0x50, %bl
xorb %bl, %al /* set %al=0x60 (01100000b) */
movb $0x30, %al
notb %al /* set %al=0xCF (11001111b) */
Multiplication
Two forms of imul instruction
Two operand: multiply operands and truncate
Example:
imulq %rdi, %rsi /* set %rsi to %rdi * %rsi, truncated to 64 bits */
One operand: multiply 64 bit operand and value in %rax, 128-bit result in %rdx:%rax
- Signed (
imulq) and unsigned (mulq) variants
Example:
mulq %rdi/* set %rdx:%rax to unsigned product %rax * %rdi */
Division
idivq and divq: signed and unsigned integer division
128-bit dividend in %rdx:%rax, 64 bit quotient in %rax, 64 bit remainder in %rdx
- For a 64 bit dividend, set
%rdxto0(unsigned division) or the replication of the sign bit of%rax(ctqoinstruction replicates the sign bit of%rax)
Example:
divq %r10 /* divide %rdx:%rax by %r10, put quotient in %rax, remainder in %rdx */
Memory Conversion
When moving a smaller source vaue to a larger destination, sign-extension (copying sign bit to the high bits) is necessary to preserve the value of a signed value.
- E.g., the value of -16381 is represented as
1100000000000011(16 bits) or11111111111111111100000000000011(32 bits).
To perform data movement with sign-extension, use movsbw, movsbl, movswl, etc. For unsigned values, data movement with zero-extension (copy 0 into high bits), use movzbw, movzbl, movzwl, etc.
Example:
movzbq %al, %rdi
- converts 8 bit
unit8_tto 64 bituint64_t
Linked from Computer System Fundamentals