CS 208 s21 — Arithmetic in x86-64 Assembly

Table of Contents

1 Arithmetic Instructions

Instruction Description Effect
inc \(D\) \(D + 1 \rightarrow D\) increment
dec \(D\) \(D - 1 \rightarrow D\) decrement
neg \(D\) \(-D \rightarrow D\) negate
not \(D\) \(~D \rightarrow D\) complement
     
add \(S,\:D\) \(D + S \rightarrow D\) add
sub \(S,\:D\) \(D - S \rightarrow D\) subtract
imul \(S,\:D\) \(D * S \rightarrow D\) multiply
xor \(S,\:D\) \(D\,\widehat{}\,S \rightarrow D\) exclusive-or
or \(S,\:D\) \(D\,\vert\,S \rightarrow D\) or
and \(S,\:D\) \(D\,\&\,S \rightarrow D\) and
     
sal \(k,\:D\) \(D\) << \(k \rightarrow D\) left shift
shl \(k,\:D\) \(D\) << \(k \rightarrow D\) left shift (same as sal)
sar \(k,\:D\) \(D\) >> \(k \rightarrow D\) arithmetic right shift
shr \(k,\:D\) \(D\) >> \(k \rightarrow D\) logical right shift

2 Thinking in Assembly

2.1 Assembly to C

A C function with the signature long f(long *p, long i) compiled to the following assembly code:

f:
    movq    %rsi, %rax
    addq    (%rdi), %rax
    movq    %rax, (%rdi)
    ret
Register Use
%rdi 1st argument (p)
%rsi 2nd argument (i)

Possible C code for this function:

long f(long *p, long i) {
    long return_value = i;  // move %rsi to %rax (%rax holds the return value for a function)
    return_value += *p;     // dereference the pointer p, add that to %rax
    *p = return_value;      // move the value in %rax to the memory location p points to
    return return_value;    // return (using %rax as the return value)
}

A more concise version that has the same effect:

long f(long *p, long i) {
    *p += i;
    return *p;
}

2.2 leaq Instruction

  • "load effective address", but more often "lovely efficient arithmetic"
  • instead of reading from the memory location given by the source operand, copies the effective address to the destination
    • generate pointers for later memory references
    • can also do a muliply and an addition in a single instruction
      • leaq 7(%rdx, %rdx, 4), %rax will set %rax equal to 5 * %rdx + 7
  • destination must be a register
  • must have the q size designation on a 64-bit system
    • lea specifically works with a memory addresses, which will always by 8 bytes on a 64-bit system
  • movq %rdx, %rax vs movq (%rdx), %rax vs leaq (%rdx), %rax
    • rdx holds 0x100, memory address 0x100 holds 0xab