Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

impl

std › x86_64 › impl

The x86-64 base instruction set: general-purpose registers, memory operands, and the core integer instructions, each emitted as its machine code.

Import a dialect rather than this module: std.x86_64.intel, std.x86_64.nasm or std.x86_64.att. Here every instruction takes its operands in order, destination first, plus a final w: 1 for 64-bit operands and 0 for 32-bit. The dialects pick w from the register’s name instead (rax or eax).

from std.x86_64.impl import *

mov rax, rbx, 1
mov rax, Mem(rsp, 8), 1

loop:
    sub rcx, 1, 1
    jne loop
48 89 d8
48 8b 44 24 08
48 81 e9 01 00 00 00
0f 85 f3 ff ff ff

Jumps and calls always use a 32-bit offset, worked out by bitter once the program is laid out; there’s no automatic choice of the short form.

Macros

reg_field

The low 3 bits of r’s number: the part a ModRM or SIB field, or an opcode, holds.

SyntaxParametersResultDescription
reg_field(r)r: Regreturns int

reg_ext

Bit 3 of r’s number, which goes in the REX prefix: 1 for r8 to r15.

SyntaxParametersResultDescription
reg_ext(r)r: Regreturns int

rex_byte

A REX prefix, 0100WRXB. w selects 64-bit operands; r, x and b are bit 3 of the ModRM.reg, SIB.index and ModRM.rm (or SIB.base, or opcode) register numbers.

SyntaxParametersResultDescription
rex_byte(w, r, x, b)w: int, r: int, x: int, b: intreturns Byte

modrm_byte

A ModRM byte: mod (2 bits), reg (3) and rm (3).

SyntaxParametersResultDescription
modrm_byte(mod, reg, rm)mod: int, reg: int, rm: intreturns Byte

sib_byte

A SIB byte: scale (2 bits, log2 of the index’s multiplier), index (3) and base (3).

SyntaxParametersResultDescription
sib_byte(scale, index, base)scale: int, index: int, base: intreturns Byte

byte_of

Byte index of value, counting from the least significant, byte 0.

SyntaxParametersResultDescription
byte_of(value, index)value: int, index: intreturns Byte

mov

SyntaxParametersResultDescription
mov rd, rs, wrd: Reg, rs: Reg, w: intemits Bytes<...>rd = rs.
mov rd, imm, wrd: Reg, imm: int, w: intemits Bytes<...>rd = imm. With w = 1 it takes a full 64-bit imm.
mov dst, rs, wdst: MemOperand, rs: Reg, w: intemits Bytes<...>Stores rs at dst.
mov rd, src, wrd: Reg, src: MemOperand, w: intemits Bytes<...>Loads the value at src into rd.
mov dst, imm, wdst: MemOperand, imm: int, w: intemits Bytes<...>Stores imm at dst: 32 bits, sign-extended to 64 when w is 1.
mov rd, src, wrd: Reg, src: RipLabel, w: intLoads the value at the label src into rd.
mov dst, rs, wdst: RipLabel, rs: Reg, w: intStores rs at the label dst.

add

SyntaxParametersResultDescription
add rd, rs, wrd: Reg, rs: Reg, w: intemits Bytes<...>rd = rd + rs.
add rd, imm, wrd: Reg, imm: int, w: intemits Bytes<...>rd = rd + imm, with a 32-bit imm sign-extended to 64 bits.
add dst, rs, wdst: MemOperand, rs: Reg, w: intemits Bytes<...>[dst] = [dst] + rs.
add dst, imm, wdst: MemOperand, imm: int, w: intemits Bytes<...>[dst] = [dst] + imm, with a 32-bit imm.
add dst, rs, wdst: RipLabel, rs: Reg, w: int[dst] = [dst] + rs, where dst is a label.

or

SyntaxParametersResultDescription
or rd, rs, wrd: Reg, rs: Reg, w: intemits Bytes<...>rd = rd | rs.
or rd, imm, wrd: Reg, imm: int, w: intemits Bytes<...>rd = rd | imm, with a 32-bit imm sign-extended to 64 bits.
or dst, rs, wdst: MemOperand, rs: Reg, w: intemits Bytes<...>[dst] = [dst] | rs.
or dst, imm, wdst: MemOperand, imm: int, w: intemits Bytes<...>[dst] = [dst] | imm, with a 32-bit imm.
or dst, rs, wdst: RipLabel, rs: Reg, w: int[dst] = [dst] | rs, where dst is a label.

and

SyntaxParametersResultDescription
and rd, rs, wrd: Reg, rs: Reg, w: intemits Bytes<...>rd = rd & rs.
and rd, imm, wrd: Reg, imm: int, w: intemits Bytes<...>rd = rd & imm, with a 32-bit imm sign-extended to 64 bits.
and dst, rs, wdst: MemOperand, rs: Reg, w: intemits Bytes<...>[dst] = [dst] & rs.
and dst, imm, wdst: MemOperand, imm: int, w: intemits Bytes<...>[dst] = [dst] & imm, with a 32-bit imm.
and dst, rs, wdst: RipLabel, rs: Reg, w: int[dst] = [dst] & rs, where dst is a label.

sub

SyntaxParametersResultDescription
sub rd, rs, wrd: Reg, rs: Reg, w: intemits Bytes<...>rd = rd - rs.
sub rd, imm, wrd: Reg, imm: int, w: intemits Bytes<...>rd = rd - imm, with a 32-bit imm sign-extended to 64 bits.
sub dst, rs, wdst: MemOperand, rs: Reg, w: intemits Bytes<...>[dst] = [dst] - rs.
sub dst, imm, wdst: MemOperand, imm: int, w: intemits Bytes<...>[dst] = [dst] - imm, with a 32-bit imm.
sub dst, rs, wdst: RipLabel, rs: Reg, w: int[dst] = [dst] - rs, where dst is a label.

xor

SyntaxParametersResultDescription
xor rd, rs, wrd: Reg, rs: Reg, w: intemits Bytes<...>rd = rd ^ rs.
xor rd, imm, wrd: Reg, imm: int, w: intemits Bytes<...>rd = rd ^ imm, with a 32-bit imm sign-extended to 64 bits.
xor dst, rs, wdst: MemOperand, rs: Reg, w: intemits Bytes<...>[dst] = [dst] ^ rs.
xor dst, imm, wdst: MemOperand, imm: int, w: intemits Bytes<...>[dst] = [dst] ^ imm, with a 32-bit imm.
xor dst, rs, wdst: RipLabel, rs: Reg, w: int[dst] = [dst] ^ rs, where dst is a label.

cmp

SyntaxParametersResultDescription
cmp rd, rs, wrd: Reg, rs: Reg, w: intemits Bytes<...>Sets the flags from rd - rs, without storing it.
cmp rd, imm, wrd: Reg, imm: int, w: intemits Bytes<...>Sets the flags from rd - imm, without storing it.
cmp dst, rs, wdst: MemOperand, rs: Reg, w: intemits Bytes<...>Sets the flags from [dst] - rs, without storing it.
cmp dst, imm, wdst: MemOperand, imm: int, w: intemits Bytes<...>Sets the flags from [dst] - imm, without storing it.
cmp dst, rs, wdst: RipLabel, rs: Reg, w: intSets the flags from [dst] - rs, where dst is a label, without storing it.

test

SyntaxParametersResultDescription
test rd, rs, wrd: Reg, rs: Reg, w: intemits Bytes<...>Sets the flags from rd & rs, without storing it.
test rd, imm, wrd: Reg, imm: int, w: intemits Bytes<...>Sets the flags from rd & imm, without storing it.
test dst, rs, wdst: MemOperand, rs: Reg, w: intemits Bytes<...>Sets the flags from [dst] & rs, without storing it.
test dst, imm, wdst: MemOperand, imm: int, w: intemits Bytes<...>Sets the flags from [dst] & imm, without storing it.
test dst, rs, wdst: RipLabel, rs: Reg, w: intSets the flags from [dst] & rs, where dst is a label, without storing it.

Mem

The memory at [base + disp]. A displacement from -128 to 127 takes one byte; any other takes four.

SyntaxParametersResultDescription
Mem(base, disp)base: Reg, disp: intreturns MemOperand

MemIndexed

The memory at [base + index * scale + disp]. scale is 1, 2, 4 or 8, and index can be any register but rsp.

from std.x86_64.impl import *

mov rax, MemIndexed(rbx, r12, 4, 0), 1
4a 8b 04 a3
from std.x86_64.impl import *

mov rax, MemIndexed(rbx, rsp, 4, 0), 1
rsp cannot be a SIB index register
SyntaxParametersResultDescription
MemIndexed(base, index, scale, disp)base: Reg, index: Reg, scale: int, disp: intreturns MemOperand

MemRipRelative

The memory at [rip + disp]: disp bytes past the end of the instruction. To address a label, use a RipLabel instead.

SyntaxParametersResultDescription
MemRipRelative(disp)disp: intreturns MemOperand

jmp

Jumps to the label target.

SyntaxParametersResultDescription
jmp targettarget: intemits Rel32Instr

call

Pushes the address of the next instruction and jumps to the label target.

SyntaxParametersResultDescription
call targettarget: intemits Rel32Instr

je

Jumps to the label target if equal (ZF = 1).

SyntaxParametersResultDescription
je targettarget: intemits Rel32Instr2

jne

Jumps to the label target if not equal (ZF = 0).

SyntaxParametersResultDescription
jne targettarget: intemits Rel32Instr2

jb

Jumps to the label target if below, unsigned (CF = 1).

SyntaxParametersResultDescription
jb targettarget: intemits Rel32Instr2

jae

Jumps to the label target if above or equal, unsigned (CF = 0).

SyntaxParametersResultDescription
jae targettarget: intemits Rel32Instr2

ja

Jumps to the label target if above, unsigned.

SyntaxParametersResultDescription
ja targettarget: intemits Rel32Instr2

jbe

Jumps to the label target if below or equal, unsigned.

SyntaxParametersResultDescription
jbe targettarget: intemits Rel32Instr2

jl

Jumps to the label target if less, signed.

SyntaxParametersResultDescription
jl targettarget: intemits Rel32Instr2

jge

Jumps to the label target if greater or equal, signed.

SyntaxParametersResultDescription
jge targettarget: intemits Rel32Instr2

jle

Jumps to the label target if less or equal, signed.

SyntaxParametersResultDescription
jle targettarget: intemits Rel32Instr2

jg

Jumps to the label target if greater, signed.

SyntaxParametersResultDescription
jg targettarget: intemits Rel32Instr2

js

Jumps to the label target if the result was negative (SF = 1).

SyntaxParametersResultDescription
js targettarget: intemits Rel32Instr2

jns

Jumps to the label target if the result wasn’t negative (SF = 0).

SyntaxParametersResultDescription
jns targettarget: intemits Rel32Instr2

jo

Jumps to the label target on signed overflow (OF = 1).

SyntaxParametersResultDescription
jo targettarget: intemits Rel32Instr2

jno

Jumps to the label target without signed overflow (OF = 0).

SyntaxParametersResultDescription
jno targettarget: intemits Rel32Instr2

jp

Jumps to the label target if the parity flag is set (PF = 1).

SyntaxParametersResultDescription
jp targettarget: intemits Rel32Instr2

jnp

Jumps to the label target if the parity flag is clear (PF = 0).

SyntaxParametersResultDescription
jnp targettarget: intemits Rel32Instr2

jz

je, under another name.

SyntaxParametersResultDescription
jz targettarget: intemits Rel32Instr2

jnz

jne, under another name.

SyntaxParametersResultDescription
jnz targettarget: intemits Rel32Instr2

jc

jb, under another name.

SyntaxParametersResultDescription
jc targettarget: intemits Rel32Instr2

jnae

jb, under another name.

SyntaxParametersResultDescription
jnae targettarget: intemits Rel32Instr2

jnc

jae, under another name.

SyntaxParametersResultDescription
jnc targettarget: intemits Rel32Instr2

jnb

jae, under another name.

SyntaxParametersResultDescription
jnb targettarget: intemits Rel32Instr2

jnbe

ja, under another name.

SyntaxParametersResultDescription
jnbe targettarget: intemits Rel32Instr2

jna

jbe, under another name.

SyntaxParametersResultDescription
jna targettarget: intemits Rel32Instr2

jnge

jl, under another name.

SyntaxParametersResultDescription
jnge targettarget: intemits Rel32Instr2

jnl

jge, under another name.

SyntaxParametersResultDescription
jnl targettarget: intemits Rel32Instr2

jng

jle, under another name.

SyntaxParametersResultDescription
jng targettarget: intemits Rel32Instr2

jnle

jg, under another name.

SyntaxParametersResultDescription
jnle targettarget: intemits Rel32Instr2

jpe

jp, under another name.

SyntaxParametersResultDescription
jpe targettarget: intemits Rel32Instr2

jpo

jnp, under another name.

SyntaxParametersResultDescription
jpo targettarget: intemits Rel32Instr2

ret

Returns: pops an address and jumps to it.

SyntaxParametersResultDescription
retemits Byte

shl

rd = rd << imm.

SyntaxParametersResultDescription
shl rd, imm, wrd: Reg, imm: int, w: intemits Bytes<...>

shl_cl

rd = rd << cl.

SyntaxParametersResultDescription
shl_cl rd, wrd: Reg, w: intemits Bytes<...>

shr

rd = rd >> imm, shifting in zeros.

SyntaxParametersResultDescription
shr rd, imm, wrd: Reg, imm: int, w: intemits Bytes<...>

shr_cl

rd = rd >> cl, shifting in zeros.

SyntaxParametersResultDescription
shr_cl rd, wrd: Reg, w: intemits Bytes<...>

sar

rd = rd >> imm, shifting in copies of the sign bit.

SyntaxParametersResultDescription
sar rd, imm, wrd: Reg, imm: int, w: intemits Bytes<...>

sar_cl

rd = rd >> cl, shifting in copies of the sign bit.

SyntaxParametersResultDescription
sar_cl rd, wrd: Reg, w: intemits Bytes<...>

lea

SyntaxParametersResultDescription
lea rd, src, wrd: Reg, src: MemOperand, w: intemits Bytes<...>Loads the address src stands for into rd, without reading memory.
lea rd, src, wrd: Reg, src: RipLabel, w: intLoads the address of the label src into rd.

rip_label_instr

An instruction with opcode opcode whose memory operand is the label addr, and whose other operand is r. The dialects’ [rel label] forms are built on it.

SyntaxParametersResultDescription
rip_label_instr opcode, addr, r, wopcode: int, addr: RipLabel, r: Reg, w: int

push

Pushes the 64-bit rd onto the stack.

SyntaxParametersResultDescription
push rdrd: Regemits Bytes<...>

pop

Pops 64 bits off the stack into rd.

SyntaxParametersResultDescription
pop rdrd: Regemits Bytes<...>

syscall

Calls the operating system. On Linux, rax holds the call number and rdi, rsi, rdx, … its arguments.

SyntaxParametersResultDescription
syscallemits Bytes<2>

Types

Reg

type Reg = bits<4>

A register number, 0 to 15. As an operand it means the whole 64-bit register.

Reg32

struct Reg32

The low 32 bits of a register. An instruction given one works on 32 bits instead of 64, and writing one zeroes the register’s upper half.

FieldTypeDescription
regRegThe register it’s the low half of.

Byte

type Byte = bits<8>

A byte.

Bytes

struct Bytes<const N: int>

N bytes, packed by bitter in order: an instruction’s encoding.

Some of its fields are generated by @for or @if.

MemBase

struct MemBase

[base + disp]. Mem builds one.

FieldTypeDescription
baseRegThe base register.
dispintThe displacement added to it.

MemSib

struct MemSib

[base + index * scale + disp]. MemIndexed builds one.

FieldTypeDescription
baseRegThe base register.
indexRegThe index register.
scaleintThe index’s multiplier: 1, 2, 4 or 8.
dispintThe displacement.

MemRip

struct MemRip

[rip + disp]. MemRipRelative builds one.

FieldTypeDescription
dispintThe displacement from the end of the instruction.

MemOperand

enum MemOperand

A memory operand, built by Mem, MemIndexed or MemRipRelative.

VariantPayloadDescription
BaseMemBase[base + disp].
IndexedMemSib[base + index * scale + disp].
RipRelativeMemRip[rip + disp].

Rel32Instr

struct Rel32Instr

A jmp or call: an opcode byte and a 32-bit offset bitter works out.

FieldTypeDescription
opcodeByteThe opcode.
rel32LittleEndian<Positioned<32>, 32>The offset from the next instruction to the target.

Rel32Instr2

struct Rel32Instr2

A conditional jump: two opcode bytes and a 32-bit offset bitter works out.

FieldTypeDescription
opcode1ByteThe first opcode byte, 0x0F.
opcode2ByteThe second opcode byte, which holds the condition.
rel32LittleEndian<Positioned<32>, 32>The offset from the next instruction to the target.

RipLabel

struct RipLabel

A label used as a memory operand, addressed relative to the next instruction: NASM’s [rel label].

FieldTypeDescription
targetintThe label.

RipRelInstr

struct RipRelInstr

An instruction with a RipLabel operand and no REX prefix.

FieldTypeDescription
opcodeByteThe opcode.
modrmByteThe ModRM byte, with rm = RIP-relative.
disp32LittleEndian<Positioned<32>, 32>The displacement from the next instruction to the label.

RipRelInstrRex

struct RipRelInstrRex

An instruction with a RipLabel operand and a REX prefix.

FieldTypeDescription
rexByteThe REX prefix.
opcodeByteThe opcode.
modrmByteThe ModRM byte, with rm = RIP-relative.
disp32LittleEndian<Positioned<32>, 32>The displacement from the next instruction to the label.

Constants

ConstantTypeValueDescription
r0Reg0A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r1Reg1A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r2Reg2A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r3Reg3A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r4Reg4A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r5Reg5A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r6Reg6A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r7Reg7A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r8Reg8A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r9Reg9A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r10Reg10A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r11Reg11A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r12Reg12A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r13Reg13A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r14Reg14A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
r15Reg15A 64-bit general-purpose register. r0 to r7 are better known as rax to rdi.
raxr0r0, the accumulator: where a function returns its result.
rcxr1r1, the counter: a function’s fourth argument.
rdxr2r2: a function’s third argument.
rbxr3r3, saved across calls.
rspr4r4, the stack pointer.
rbpr5r5, the frame pointer, saved across calls.
rsir6r6: a function’s second argument.
rdir7r7: a function’s first argument.
eaxReg32(reg = rax)The low 32 bits of rax.
ecxReg32(reg = rcx)The low 32 bits of rcx.
edxReg32(reg = rdx)The low 32 bits of rdx.
ebxReg32(reg = rbx)The low 32 bits of rbx.
espReg32(reg = rsp)The low 32 bits of rsp.
ebpReg32(reg = rbp)The low 32 bits of rbp.
esiReg32(reg = rsi)The low 32 bits of rsi.
ediReg32(reg = rdi)The low 32 bits of rdi.
r8dReg32(reg = r8)The low 32 bits of r8.
r9dReg32(reg = r9)The low 32 bits of r9.
r10dReg32(reg = r10)The low 32 bits of r10.
r11dReg32(reg = r11)The low 32 bits of r11.
r12dReg32(reg = r12)The low 32 bits of r12.
r13dReg32(reg = r13)The low 32 bits of r13.
r14dReg32(reg = r14)The low 32 bits of r14.
r15dReg32(reg = r15)The low 32 bits of r15.