CO Lab Manual
Course Page
  • Course Information
    • Welcome
    • Introduction
    • Your Contributions
    • Lab Sessions and Etiquette
    • Team Setup
    • Assumed Prior Knowledge
  • Setup Guides
    • GitHub Repository Setup
    • Technical Setup
      • Windows
      • Linux
      • macOS
    • GitHub SSH Setup
    • Framework Setup
  • Reference Documentation
    • Introduction to the Documentation
    • A Brief History Lesson
    • Syntax (Intel vs. AT&T)
      • Section Exercises
    • Memory
      • Memory Management
      • Section Exercises
    • Registers
      • Section Exercises
    • Instructions
    • Subroutines
      • Calling Subroutines
      • Writing Subroutines
      • Section Exercises
    • Input/Output
      • Printing to the Terminal
      • Reading from the Terminal
      • Section Exercises
    • Programming Constructs
    • Assembler Directives
    • C/C++ vs Assembly
    • Building and Running Programs
    • Address Sanitization
    • A0: A Running Example
  • Assignments
    • Introduction to the Assignments
    • Mandatory Assignments
      • A1: Subroutines and I/O
      • A2: Recursion
    • Extra Assignments
      • A3-a: Fibonacci Calculator
      • A3-b: Fibonacci REPL
      • A4: Diff
      • A5: Printf
      • A6: HPC
      • A7: Bitmap
      • A8: Game
  • Appendix
    • Acknowledgments
    • Rules and Regulations
    • Frequently Asked Questions
    • How to use a Debugger
Powered by GitBook
On this page
  • Addressing Modes
  • Note on Order of Operands
  1. Reference Documentation

Instructions

PreviousSection ExercisesNextSubroutines

Last updated 3 months ago

As x86-64 is a CISC architecture, it has a vast range of different instructions (, not counting different operand types for the same instruction), varying in complexity. Below are some of the most commonly used/most important instructions, grouped by functionality. For those interested in a more extensive set of instructions, the official is a nice (and with ~5,000 pages fairly light) read.

Note that a . postfix is a placeholder for a size indicator, so either b(byte), w (word), l (long), or q (quadword). Some instructions allow only a subset of these postfixes.

Mnemonic
Operands
Action

mov.

SRC, DST

DST = SRC

push.

SRC

rsp -= <#bytes>; (rsp) = SRC

pop.

DST

DST = (rsp); rsp += <#bytes>

xchg.

A, B

TMP = A; A = B; B = TMP

movzb.

SRC, DST

DST = SRC (one byte only, higher-order bits set to zero)

movzw.

SRC, DST

DST = SRC (one word only, higher-order bits set to zero)

lea.

A, DST

DST = &A (address of A)

Mnemonic
Operands
Action

add.

SRC, DST

DST = DST + SRC

sub.

SRC, DST

DST = DST - SRC

inc.

DST

DST = DST + 1

dec.

DST

DST = DST - 1

mul.

SRC

rdx:rax = rax * SRC (unsigned)

imul.

SRC

rdx:rax = rax * SRC

imul.

SRC, DST

DST = SRC * DST

imul.

C, SRC, DST

DST = C * SRC

(i)div.

SRC

rax = rdx:rax / SRC; rdx = rdx:rax % SRC

rdx:rax represents a 128-bit value where the most significant 64 bits are in rdx and the least significant 64 bits are in rax

Mnemonic
Operands
Action

cmp.

A, B

B - A (only set flags)

or.

SRC, DST

DST = SRC | DST (bitwise)

and.

SRC, DST

DST = SRC & DST (bitwise)

xor.

SRC, DST

DST = SRC ^ DST (bitwise)

neg.

DST

DST = !DST (bitwise)

shl.

C, DST

DST = DST << C (overflowing bits discarded)

shr.

C, DST

DST = DST >> C (underflowing bits discarded)

rol.

C, DST

DST = DST << C (overflowing bits become least sig. bits)

ror.

C, DST

DST = DST >> C (underflowing bits become most sig. bits)

Mnemonic
Operands
Action

call

ADDR

jump to ADDR and push return address

ret

pop address and jump to it

cmp.

A, B

B - A (only set flags, see below)

test.

A, B

A & B (only set flags, see below)

All conditional branch instructions (except jrcxz, jecxz, and jcxz) use the state of the processor flags to decide whether or not to perform the jump. The flags are (among others) set through the result of arithmetic instructions (like cmp or test). x86-64 processors have a large set of flags, below are the ones commonly used for conditional jumps:

  • Carry Flag (CF): set on high-order bit carry or borrow (cleared otherwise)

  • Parity Flag (PF): set if low-order 8 bits contain an even number of '1' bits (cleared otherwise)

  • Zero Flag (ZF): set if the result is zero (cleared otherwise)

  • Sign Flag (SF): set to equal high-order bit of result

  • Overflow Flag (OF): set if the result is too large of a positive number or too small of a negative number (excluding sign bit) to fit the destination operand (cleared otherwise)

All following instructions take the location to jump to as their only operand.

Mnemonic
Condition
Flags

jmp

jo

overflow

OF

jno

no overflow

!OF

js

sign bit (negative number)

SF

jns

no sign bit

!SF

je / jz

equal / zero

ZF

jne / jnz

not equal / not zero

!ZF

jb / jnae / jc

below / not above or equal / carry (unsigned)

CF

jnb / jae / jnc

not below / above or equal / not carry (unsigned)

!CF

jbe / jna

below or equal / not above (unsigned)

CF or ZF

ja/ jnbe

above / not below or equal (unsigned)

!CF and !ZF

jl / jnge

less / not greater or equal (signed)

SF != OF

jge / jnl

greater or equal / not less (signed)

SF = OF

jle / jng

less or equal / not greater (signed)

ZF or (SF != OF)

jg / jnle

greater / not less or equal (signed)

!ZF and (SF = OF)

jp / jpe

parity / parity even

PF

jnp / jpo

not parity / parity odd

!PF

jrcxz

rcx register is 0 (loop counter at 0)

rcx = 0

jecxz

ecx register is 0 (loop counter at 0)

ecx = 0

jcxz

cx register is 0 (loop counter at 0)

cx = 0


Addressing Modes

The x86-64 architecture allows for many different (memory) addressing modes. Below are some of the most commonly used:

Name
Syntax
Description

Immediate

move the a value 1 into the register rax

Register

move (copy) the contents (8 bytes) from the register rdi into the register rax

Indirect

move 8 bytes from memory starting at the address stored in rdi into the register rax

Base and Displacement

move 8 bytes from memory starting at the address: rdi - 8 into the register rax The displacement may be any positive or negative value.

Base and Index

move 8 bytes from memory starting at the address: rdi + rbx into the register rax

Base, Index, and Scale

move 8 bytes from memory starting at the address: rdi + (rbx * 4) into the register rax

The scale factor may be either 1, 2, 4, or 8.

Base, Index, Scale, and Displacement

move 8 bytes from memory starting at the address: rdi + (rbx * 4) + 16 into the register rax

The displacement may be any positive or negative value.

Note on Order of Operands

For all of these modes, except Immediate, the order of operands given in the example may also be reversed (to use the addressing for the destination instead of the source operand). However, at least one of the operands needs to be a register or intermediate value, so the following would not be a valid instruction:

movq    (%rax), (%rdi)

as both the source and destination operands are memory locations.

movq $1, %rax
movq %rdi, %rax
movq (%rdi), %rax
movq -8(%rdi), %rax
movq (%rdi, %rbx), %rax
movq (%rdi, %rbx, 4), %rax
movq 16(%rdi, %rbx, 4), %rax
about ~980
Intel Manual