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 to5 * %rdx + 7
- destination must be a register
- must have the
q
size designation on a 64-bit systemlea
specifically works with a memory addresses, which will always by 8 bytes on a 64-bit system
movq %rdx, %rax
vsmovq (%rdx), %rax
vsleaq (%rdx), %rax
- rdx holds 0x100, memory address 0x100 holds 0xab