x86-64 registers & flags
Registers
Sixteen 64 bit general purpose registers. Each one can be used at four widths: rax is the whole register, eax its low 32 bits, ax its low 16 and al its low 8. Writing a 32 bit name clears the top half of the 64 bit register; writing a 16 or 8 bit name leaves the rest alone.
rax
eax, ax, ah, alThe accumulator. mul, div and the string instructions use it without being told to, a syscall number goes in it, and a syscall result comes back in it.
rbx
ebx, bx, bh, blA general register. Called on to survive a function call: a function that writes to it has to put it back before returning.
rcx
ecx, cx, ch, clThe counter. loop and the repeated string instructions count down with it, the shift instructions read a variable shift amount from cl, and it carries the fourth argument of a function call. syscall destroys it.
rdx
edx, dx, dh, dlThe high half of the product mul writes and of the dividend div reads, and the third argument of a function call or a syscall.
rsi
esi, si, silThe source pointer of the string instructions, and the second argument of a function call or a syscall.
rdi
edi, di, dilThe destination pointer of the string instructions, and the first argument of a function call or a syscall.
rbp
ebp, bp, bplThe frame pointer by convention, pointing at the base of the current function's stack frame. Nothing in the hardware requires it, and compilers routinely use it as one more general register.
rsp
esp, sp, splThe stack pointer. push, pop, call and ret move it without being told to, and it must point at usable memory whenever any of them runs.
r8 to r15
r8d to r15d, r8w to r15w, r8b to r15bThe eight registers x86-64 added. r8 and r9 carry the fifth and sixth arguments of a function call; r10 replaces rcx as the fourth argument of a syscall, because syscall destroys rcx. r11 is destroyed too.
rip
The instruction pointer. It cannot be read or written directly, but it can be addressed: [rel label] assembles to an offset from rip, which is how position independent code reaches its own data.
rflags
eflags, flagsThe flags, listed below. Arithmetic and logic instructions write them, the conditional jumps and setcc read them, and pushfq and popfq move the whole register to and from the stack.
Flags
The flags live in rflags. Arithmetic and logic instructions write them, cmp and test exist to write them without keeping a result, and the conditional instructions read them.
CF
bit 0Carry. Set when an unsigned addition overflowed or an unsigned subtraction borrowed, and by the shift and rotate instructions, which shift the last bit out through it.
PF
bit 2Parity. Set when the low byte of the result has an even number of set bits.
AF
bit 4Adjust. The carry out of bit 3, which only the decimal adjust instructions read.
ZF
bit 6Zero. Set when the result was zero, which is what je and jne read after a cmp.
SF
bit 7Sign. A copy of the top bit of the result, so it is set when the result is negative read as signed.
DF
bit 10Direction. Clear means the string instructions count upwards, set means downwards. cld and std write it, and it is expected to be clear everywhere else.
OF
bit 11Overflow. Set when a signed operation produced a result too large for its destination, which is a different question from the one the carry flag answers.
SSE registers
Floating point arithmetic in a 64 bit program is SSE arithmetic. The xmm registers are wide enough to hold several numbers at once, and each instruction says how much of a register it means: the scalar forms work on the lowest lane alone, so addsd xmm0, xmm1 adds one pair of doubles and cvtsi2sd xmm0, rax turns an integer into a double and writes it into that same lowest lane, both of them leaving the upper lane of the destination as they found it. The moves are the exception: movsd xmm0, [x] loads one double from memory and clears bits 127 to 64, while movsd xmm0, xmm1 copies the low double and leaves the upper lane alone, so where the value came from decides what the rest of the register holds. The packed forms, addpd and mulps among them, apply the same operation to every lane of the register at once, which is the reason the registers are this wide.
The single precision instructions are spelled with ss and ps where the double precision ones use sd and pd, and the calling convention passes floating point arguments in xmm0 to xmm7 and returns them in xmm0.
xmm0 to xmm15
128 bitSixteen 128 bit registers. Read as doubles they are two lanes, read as singles four, and read as raw bits sixteen bytes; the registers panel shows all three, because nothing in the register itself records which one the program meant.
mxcsr
32 bitThe control and status register of the unit. It holds the rounding mode, the masks that decide whether an invalid operation raises an exception or quietly produces a NaN, and the flags that record which of those conditions has happened since the flags were last cleared. ldmxcsr and stmxcsr move it to and from memory.
x87 registers
The x87 unit is the floating point hardware x86 had before SSE, and it is still what the f instructions use. Its eight registers are a stack rather than a numbered file: st0 is always the top, fld and fld1 push a value onto it and rename everything below, and faddp adds the top two and pops, so the same register name means a different value after every push. Programs written today use SSE for arithmetic and reach for x87 mainly for the operations SSE has no instruction for, such as fsin, fcos or fpatan.
This emulator keeps the stack as ordinary 64 bit doubles rather than the 80 bit extended values real hardware computes with, so a long chain of x87 arithmetic can differ from a physical processor in the last bits of the result.
A slot the stack has not filled, or has popped, keeps whatever bits it last held. The panel shows those rows blank rather than the stale value, the way info float prints Empty in gdb, and the bits are still a hover away; ftag is the register that says which slots are live.
st0 to st7
64 bitThe stack registers, listed top first: what the panel calls st0 is whatever the last push left on top, and one more push moves that value to st1. An instruction that pops past the bottom of the stack, or pushes onto a full one, raises the stack fault the status word reports.
fctrl
16 bitThe control word: the rounding mode, the precision the unit rounds results to, and the masks that say which exceptions the program wants to be told about. fldcw writes it, which is how code that needs truncation rather than the default round to nearest gets it. The precision field has nothing to decide here, because the stack already holds doubles.
fstat
16 bitThe status word: the exception flags, the condition codes a comparison such as fcom writes, and the three bits that say which register is currently the top of the stack. fstsw ax copies it into ax, which is how an x87 comparison used to reach a conditional jump.
ftag
16 bitTwo bits per register saying whether it holds a number, a zero, a special value such as an infinity, or nothing at all. It is what makes an empty stack slot distinguishable from one holding zero, and what the panel reads to decide which rows to leave blank.
Condition codes
The same sixteen conditions end jcc, setcc and cmovcc: jne jumps, setne writes 1 or 0 to a byte, and cmovne copies a register, all on the same test. The unsigned conditions read the carry flag and the signed ones read the sign and overflow flags, which is why comparing two numbers the wrong way round silently gives the wrong answer.
e
ZF = 1- Also written
z- Meaning
- equal, zero
- Test
ZF = 1
ne
ZF = 0- Also written
nz- Meaning
- not equal, not zero
- Test
ZF = 0
a
CF = 0 and ZF = 0- Also written
nbe- Meaning
- above (unsigned)
- Test
CF = 0 and ZF = 0
ae
CF = 0- Also written
nb,nc- Meaning
- above or equal (unsigned)
- Test
CF = 0
b
CF = 1- Also written
nae,c- Meaning
- below (unsigned)
- Test
CF = 1
be
CF = 1 or ZF = 1- Also written
na- Meaning
- below or equal (unsigned)
- Test
CF = 1 or ZF = 1
g
ZF = 0 and SF = OF- Also written
nle- Meaning
- greater (signed)
- Test
ZF = 0 and SF = OF
ge
SF = OF- Also written
nl- Meaning
- greater or equal (signed)
- Test
SF = OF
l
SF is not OF- Also written
nge- Meaning
- less (signed)
- Test
SF is not OF
le
ZF = 1 or SF is not OF- Also written
ng- Meaning
- less or equal (signed)
- Test
ZF = 1 or SF is not OF
s
SF = 1- Meaning
- sign set, negative
- Test
SF = 1
ns
SF = 0- Meaning
- sign clear, not negative
- Test
SF = 0
o
OF = 1- Meaning
- overflow
- Test
OF = 1
no
OF = 0- Meaning
- no overflow
- Test
OF = 0
p
PF = 1- Also written
pe- Meaning
- parity even
- Test
PF = 1
np
PF = 0- Also written
po- Meaning
- parity odd
- Test
PF = 0