Accumulator register (AX). Used in arithmetic operations
Counter register (CX). Used in shift/rotate instructions and loops.
Data register (DX). Used in arithmetic operations and I/O operations.
Base register (BX). Used as a pointer to data (located in segment register DS, when in segmented mode).
Stack Pointer register (SP). Pointer to the top of the stack.
Stack Base Pointer register (BP). Used to point to the base of the stack.
Source Index register (SI). Used as a pointer to a source in stream operations.
Destination Index register (DI). Used as a pointer to a destination in stream operations.
All registers can be accessed in 16-bit and 32-bit modes. In 16-bit mode, the register is identified by its two-letter abbreviation from the list above. In 32-bit mode, this two-letter abbreviation is prefixed with an 'E' (extended). For example, 'EAX' is the accumulator register as a 32-bit value.
Similarly, in the 64-bit version, the 'E' is replaced with an 'R', so the 64-bit version of 'EAX' is called 'RAX'.
It is also possible to address the first four registers (AX, CX, DX and BX) in their size of 16-bit as two 8-bit halves. The least significant byte (LSB), or low half, is identified by replacing the 'X' with an 'L'. The most significant byte (MSB), or high half, uses an 'H' instead. For example, CL is the LSB of the counter register, whereas CH is its MSB.
In total, this gives us five ways to access the accumulator, counter, data and base registers: 64-bit, 32-bit, 16-bit, 8-bit LSB, and 8-bit MSB. The other four are accessed in only three ways: 64-bit, 32-bit and 16-bit. The following table summarises this:
Segment Registers
The 6 Segment Registers are:
Stack Segment (SS). Pointer to the stack.
Code Segment (CS). Pointer to the code.
Data Segment (DS). Pointer to the data.
Extra Segment (ES). Pointer to extra data ('E' stands for 'Extra').
F Segment (FS). Pointer to more extra data ('F' comes after 'E').
G Segment (GS). Pointer to still more extra data ('G' comes after 'F').
EFLAGS Register
The EFLAGS is a 32-bit register used as a collection of bits representing Boolean values to store the results of operations and the state of the processor.
The bits named 0 and 1 are reserved bits and shouldn't be modified.
The different use of these flags are:
CF
Carry Flag. Set if the last arithmetic operation carried (addition) or borrowed (subtraction) a bit beyond the size of the register. This is then checked when the operation is followed with an add-with-carry or subtract-with-borrow to deal with values too large for just one register to contain.
0:000> bp $exentry
*** WARNING: Unable to verify checksum for EIP.exe
0:000> bl
0 e 00411109 0001 (0001) 0:**** EIP!ILT+260(_mainCRTStartup)
0:000> g
Breakpoint 0 hit
eax=7529ef9a ebx=7ffda000 ecx=00000000 edx=00411109 esi=00000000 edi=00000000
eip=00411109 esp=0012ff8c ebp=0012ff94 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
EIP!ILT+260(_mainCRTStartup):
00411109 e9c2060000 jmp EIP!mainCRTStartup (004117d0)
0:000> p
eax=7529ef9a ebx=7ffda000 ecx=00000000 edx=00411109 esi=00000000 edi=00000000
eip=004117d0 esp=0012ff8c ebp=0012ff94 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
EIP!mainCRTStartup:
004117d0 8bff mov edi,edi
0:000> r eip
eip=004117d0
0:000> x EIP!EipTrigger
00411390 EIP!EipTrigger (void)
0:000> r eip=00411390
0:000> g
ModLoad: 74da0000 74dec000 C:\Windows\system32\apphelp.dll
eax=00000172 ebx=00000000 ecx=fba6ad26 edx=0012fe6c esi=77008380 edi=77008340
eip=76f76bb4 esp=0012fe64 ebp=0012fe80 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!KiFastSystemCallRet:
76f76bb4 c3 ret
Memory
The x86 architecture is little-endian, meaning that multi-byte values are written least significant byte first. (This refers only to the ordering of the bytes, not to the bits.)
The x86 architecture has
64-bit x86 has additional registers.
General-Purpose Registers (GPR)
The 8 GPRs are:
All registers can be accessed in 16-bit and 32-bit modes. In 16-bit mode, the register is identified by its two-letter abbreviation from the list above. In 32-bit mode, this two-letter abbreviation is prefixed with an 'E' (extended). For example, 'EAX' is the accumulator register as a 32-bit value.
Similarly, in the 64-bit version, the 'E' is replaced with an 'R', so the 64-bit version of 'EAX' is called 'RAX'.
It is also possible to address the first four registers (AX, CX, DX and BX) in their size of 16-bit as two 8-bit halves. The least significant byte (LSB), or low half, is identified by replacing the 'X' with an 'L'. The most significant byte (MSB), or high half, uses an 'H' instead. For example, CL is the LSB of the counter register, whereas CH is its MSB.
In total, this gives us five ways to access the accumulator, counter, data and base registers: 64-bit, 32-bit, 16-bit, 8-bit LSB, and 8-bit MSB. The other four are accessed in only three ways: 64-bit, 32-bit and 16-bit. The following table summarises this:
Segment Registers
The 6 Segment Registers are:
EFLAGS Register
The EFLAGS is a 32-bit register used as a collection of bits representing Boolean values to store the results of operations and the state of the processor.
The bits named 0 and 1 are reserved bits and shouldn't be modified.
The different use of these flags are:
Carry Flag. Set if the last arithmetic operation carried (addition) or borrowed (subtraction) a bit beyond the size of the register. This is then checked when the operation is followed with an add-with-carry or subtract-with-borrow to deal with values too large for just one register to contain.
Parity Flag. Set if the number of set bits in the least significant byte is a multiple of 2.
Zero Flag. Set if the result of an operation is Zero (0).
Sign Flag. Set if the result of an operation is negative.
Instruction Pointer
The EIP register contains the address of the next instruction to be executed if no branching is done.
EIP can only be read through the stack after a call instruction. Let's a demo for shellcode execution.
Memory
The x86 architecture is little-endian, meaning that multi-byte values are written least significant byte first. (This refers only to the ordering of the bytes, not to the bits.)
References