[][src]Module inc::x86

A general purpose x86 library.

Getting started

The easiest way to learn assembly is to write very simple C programs and look at the generated code. Clang and GCC support -S flag to output the assembly instead of a binary executable.

Some reasonably good tutorials are:

  1. x86 Assembly Guide 1
  2. x86 Assembly Guide 2
  3. Ops like .p2align are not x86 instructions but GNU assembly directives. See GNU assembler docs.

Syntax

Intel syntax is used everywhere instead of AT&T, which is so much more painful to read.

  1. x86 assembly language | Syntax
  2. AT&T Syntax versus Intel Syntax

Portability

This should work on osx and Linux. Platform specific code is annotated and picked at compile time where possible.

  1. Writing 64 Bit Assembly on Mac OS X

Calling conventions on x86

The history of calling conventions, part 1 is a really good read on this subject.

C Declaration (cdecl)

cdecl mandates that all arguments are passed in stack in reverse order (right to left) above the stack pointer. The caller cleans up the stack because the callee might not know how many arguments were present (hint: variadic arguments). See history for details.

Most literature and documentation suggests that this is the default convention used by Clang and GCC on Linux, but in practice compilers seems to default to System V instead.

Inc style

This paper implements a variation of cdecl for simplicity - mainly because register allocation is a fairly hard problem. This is incidentally very similar to the Pascal style.

All arguments are passed in stack left to right below the stack pointer. Stack space is reclaimed by subsequent calls and is not implicitly cleaned.

System V AMD64 ABI

GCC on x86-64 seems to be actually using System V AMD64 ABI. User defined functions, primitives as well as FFI into C must use this convention for simplicity when possible.

Arguments are passed in the registers RDI, RSI, RDX, RCX, R8, R9 and the return value is passed back in RAX. Functions preserve the registers RBX, RSP, RBP, R12, R13, R14, and R15; while RAX, RDI, RSI, RDX, RCX, R8, R9, R10, R11 are scratch registers.

Reference Reading

  1. x86 calling conventions
  2. System V ABI
  3. System V Application Binary Interface

Structs

ASM

ASM represents a list of instructions

Ins

An x86 instruction

Relative

Relative addressing modes for memory access

Enums

Reference

A Reference is a valid address to an x86 instruction.

Register

An x86 register

Constants

SYS_V

Registers for argument passing

WORDSIZE

Word size of the architecture

Functions

add

Add v to register r

and

Logical and of v to register r

call

Unconditional function call

cmp

Compares the first source operand with the second source operand and sets the status flags in the EFLAGS register.

enter

x86 function preamble

func
init
init_heap

The base address of the heap is passed in RDI and we reserve reg R12 for it.

je

Jump to the specified label if last comparison resulted in equality

jmp

Unconditionally jump to the specified label

label

A label is a target to jump to

lea

Load effective address of a label into register r with an offset

leave

Exit a function and clean up. See Enter

load

Load a value at stack index si to register r

mov

Mov! At least one of the operands must be a register, moving from RAM to RAM isn't a valid op.

mul

Multiply register AX with value v and move result to register RAX

or

Logical or of v to register r

pop

Pop a register r from stack

prelude
push

Push a register r to stack

ret

Return from the calling function

sal

Shift register r left by v bits; r = r * 2^v

sar

Shift register r right by v bits; r = r / 2^v

save

Save a reference r to stack at index si.

sub

Sub k from register r