Difference between revisions of "Assembler"

From Cheat Engine
Jump to navigation Jump to search
(Opcodes)
(Opcodes)
 
(32 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{NeedWork}}
+
[[Category:Assembler]]
To describe:
+
== Registers ==
* Flags
+
 
* Segments
+
==== 16 bit ====
* CPL/DPL
+
There are fourteen 16-bit registers.
* IDT/GDT(/LDT)
+
Four of them (AX, BX, CX, DX) are general-purpose registers (GPRs).
 +
Although each may have an additional purpose; for example, only CX can be used as a counter with the loop instruction.
 +
Each can be accessed as two separate bytes (thus BX's high byte can be accessed as BH and low byte as BL).
 +
Two pointer registers have special roles: SP (stack pointer) points to the "top" of the stack,
 +
and BP (base pointer) is often used to point at some other place in the stack,
 +
typically above the local variables (see frame pointer).
 +
The registers SI, DI, BX and BP are address registers, and may also be used for array indexing.<small>[1]</small>
 +
 
 +
Four segment registers (CS, DS, SS and ES) are used to form a memory address.
 +
The FLAGS register contains flags such as carry flag, overflow flag and zero flag.
 +
Finally, the instruction pointer (IP) points to the next instruction that will be fetched from memory and then executed;
 +
this register cannot be directly accessed (read or written) by a program.<small>[1]</small>
 +
 
 +
==== 32 bit ====
 +
With the advent of the 32-bit processor, the 16-bit general-purpose registers, base registers, index registers,
 +
instruction pointer, and FLAGS register, but not the segment registers, were expanded to 32 bits.
 +
The nomenclature represented this by prefixing an "E" (for "extended") to the register names in x86 assembly language.
 +
Thus, the AX register corresponds to the lowest 16 bits of the new 32-bit EAX register,
 +
SI corresponds to the lowest 16 bits of ESI, and so on. The general-purpose registers, base registers,
 +
and index registers can all be used as the base in addressing modes,
 +
and all of those registers except for the stack pointer can be used as the index in addressing modes.<small>[1]</small>
 +
 
 +
Two new segment registers (FS and GS) were added.
 +
With a greater number of registers, instructions and operands, the machine code format was expanded.
 +
To provide backward compatibility, segments with executable code can be marked as
 +
containing either 16-bit or 32-bit instructions.
 +
Special prefixes allow inclusion of 32-bit instructions in a 16-bit segment or vice versa.<small>[1]</small>
 +
 
 +
The 80387 processor line added eight 80-bit wide (FPU) registers: st(0) to st(7).<small>[1]</small>
 +
 
 +
With the Pentium III, Intel added eight 128-bit SSE floating point registers (XMM0 to XMM7).<small>[1]</small>
 +
 
 +
There are more 32 bit registers but this gets into some that are rarely used, and processor family specific registers.<small>[1]</small>
 +
 
 +
==== 64 bit ====
 +
Starting with the AMD Opteron processor, the x86 architecture extended the 32-bit registers
 +
into 64-bit registers in a way similar to how the 16 to 32-bit extension took place.
 +
An R-prefix identifies the 64-bit registers (RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, RFLAGS, RIP),
 +
and eight additional 64-bit general registers (R8-R15) were also introduced in the creation of x86-64.
 +
However, these extensions are only usable in 64-bit mode, which is one of the two modes only available in long mode.<small>[1]</small>
 +
 
 +
==== 128 bit ====
 +
SIMD registers XMM0–XMM15.<small>[1]</small>
 +
 
 +
 
 +
=== Purpose ===
 +
Although the main registers (with the exception of the instruction pointer) are "general-purpose"
 +
in the 32-bit and 64-bit versions of the instruction set and can be used for anything,
 +
it was originally envisioned that they be used for the following purposes:
 +
* '''AL'''/'''AH'''/'''AX'''/'''EAX'''/'''RAX''': Accumulator
 +
* '''BL'''/'''BH'''/'''BX'''/'''EBX'''/'''RBX''': Base index (for use with arrays)
 +
* '''CL'''/'''CH'''/'''CX'''/'''ECX'''/'''RCX''': Counter (for use with loops and strings)
 +
* '''DL'''/'''DH'''/'''DX'''/'''EDX'''/'''RDX''': Extend the precision of the accumulator (e.g. combine 32-bit EAX and EDX for 64-bit integer operations in 32-bit code)
 +
* '''SI'''/'''ESI'''/'''RSI''': Source index for string operations.
 +
* '''DI'''/'''EDI'''/'''RDI''': Destination index for string operations.
 +
* '''SP'''/'''ESP'''/'''RSP''': Stack pointer for top address of the stack.
 +
* '''BP'''/'''EBP'''/'''RBP''': Stack base pointer for holding the address of the current stack frame.
 +
* '''IP'''/'''EIP'''/'''RIP''': Instruction pointer. Holds the program counter, the current instruction address.
 +
 
 +
Segment registers:
 +
* '''CS''': Code
 +
* '''DS''': Data
 +
* '''SS''': Stack
 +
* '''ES''': Extra data
 +
* '''FS''': Extra data #2
 +
* '''GS''': Extra data #3
 +
 
 +
No particular purposes were envisioned for the other 8 registers available only in 64-bit mode.<small>[1]</small>
 +
 
 +
 
 +
=== Structure ===
 +
 
 +
{| class="gallery" style="background-color:#f4f4f4"
 +
|+ General Purpose Registers (A, B, C and D)
 +
! style="width:50pt;"| 64
 +
! style="width:50pt;"| 56
 +
! style="width:50pt;"| 48
 +
! style="width:50pt;"| 40
 +
! style="width:50pt;"| 32
 +
! style="width:50pt;"| 24
 +
! style="width:50pt;"| 16
 +
! style="width:50pt;"| 8
 +
|-
 +
| colspan="8" style="text-align:center;"| R?X
 +
|-
 +
| colspan="4" style="background:lightgrey" |
 +
| colspan="4" style="text-align:center;"| E?X
 +
|-
 +
| colspan="6" style="background:lightgrey" |
 +
| colspan="2" style="text-align:center;"| ?X
 +
|-
 +
| colspan="6" style="background:lightgrey" |
 +
| style="text-align:center;"| ?H
 +
| style="text-align:center;"| ?L
 +
|}
 +
 
 +
{| class="gallery" style="background-color:#f4f4f4"
 +
|+ 64-bit mode-only General Purpose Registers (R8, R9, R10, R11, R12, R13, R14, R15)
 +
! style="width:50pt;"| 64
 +
! style="width:50pt;"| 56
 +
! style="width:50pt;"| 48
 +
! style="width:50pt;"| 40
 +
! style="width:50pt;"| 32
 +
! style="width:50pt;"| 24
 +
! style="width:50pt;"| 16
 +
! style="width:50pt;"| 8
 +
|-
 +
| colspan="8" style="text-align:center;"| ?
 +
|-
 +
| colspan="4" style="background:lightgrey" |
 +
| colspan="4" style="text-align:center;"| ?D
 +
|-
 +
| colspan="6" style="background:lightgrey" |
 +
| colspan="2" style="text-align:center;"| ?W
 +
|-
 +
| colspan="7" style="background:lightgrey" |
 +
| style="text-align:center;"| ?B
 +
|}
 +
 
 +
{| class="gallery" style="background-color:#f4f4f4"
 +
|+ Segment Registers<br />(C, D, S, E, F and G)
 +
! style="width:50pt;"| 16
 +
! style="width:50pt;"| 8
 +
|-
 +
| colspan="2" style="text-align:center;"| ?S
 +
|}
 +
 
 +
{| class="gallery" style="background-color:#f4f4f4"
 +
|+ Pointer Registers (S and B)
 +
! style="width:50pt;"| 64
 +
! style="width:50pt;"| 56
 +
! style="width:50pt;"| 48
 +
! style="width:50pt;"| 40
 +
! style="width:50pt;"| 32
 +
! style="width:50pt;"| 24
 +
! style="width:50pt;"| 16
 +
! style="width:50pt;"| 8
 +
|-
 +
| colspan="8" style="text-align:center;"| R?P
 +
|-
 +
| colspan="4" style="background:lightgrey" |
 +
| colspan="4" style="text-align:center;"|E?P
 +
|-
 +
| colspan="6" style="background:lightgrey" |
 +
| colspan="2" style="text-align:center;"|?P
 +
|-
 +
| colspan="7" style="background:lightgrey" |
 +
| style="text-align:center;"| ?PL
 +
|}
 +
Note: The ?PL registers are only available in 64-bit mode.<small>[1]</small>
 +
 
 +
{| class="gallery" style="background-color:#f4f4f4"
 +
|+ Index Registers (S and D)
 +
! style="width:50pt;"| 64
 +
! style="width:50pt;"| 56
 +
! style="width:50pt;"| 48
 +
! style="width:50pt;"| 40
 +
! style="width:50pt;"| 32
 +
! style="width:50pt;"| 24
 +
! style="width:50pt;"| 16
 +
! style="width:50pt;"| 8
 +
|-
 +
| colspan="8" style="text-align:center;"| R?I
 +
|-
 +
| colspan="4" style="background:lightgrey" |
 +
| colspan="4" style="text-align:center;"| E?I
 +
|-
 +
| colspan="6" style="background:lightgrey" |
 +
| colspan="2" style="text-align:center;"| ?I
 +
|-
 +
| colspan="7" style="background:lightgrey" |
 +
| style="text-align:center;"| ?IL
 +
|}
 +
Note: The ?IL registers are only available in 64-bit mode.<small>[1]</small>
 +
 
 +
{| class="gallery" style="background-color:#f4f4f4"
 +
|+ Instruction Pointer Register (I)
 +
! style="width:50pt;"| 64
 +
! style="width:50pt;"| 56
 +
! style="width:50pt;"| 48
 +
! style="width:50pt;"| 40
 +
! style="width:50pt;"| 32
 +
! style="width:50pt;"| 24
 +
! style="width:50pt;"| 16
 +
! style="width:50pt;"| 8
 +
|-
 +
| colspan="8" style="text-align:center;"| RIP
 +
|-
 +
| colspan="4" style="background:lightgrey" |
 +
| colspan="4" style="text-align:center;"| EIP
 +
|-
 +
| colspan="6" style="background:lightgrey" |
 +
| colspan="2" style="text-align:center;"| IP
 +
|}
 +
 
 +
 
 +
[[File:Table of x86 Registers svg.svg.png]]<small>[4]</small>
 +
 
  
 
== Segments ==
 
== Segments ==
Segment registers: cs,es,ds,ss,fs,gs<br>
+
Segment registers: '''CS''','''ES''','''DS''','''SS''','''FS''','''GS'''
Bits 0,1 describe the RPL , request privilege level<br>
+
:Bits 0, 1 describe the RPL, request privilege level
Bit 2 describes if the LDT is used or not<br>
+
:Bit 2 describes if the LDT is used or not
Bits 3 to 15 contain the offset into the GDT or LDT table (when shifted left by 3)
+
:Bits 3 to 15 contain the offset into the GDT or LDT table (when shifted left by 3)
 +
:Example:
 +
::CS of 8 = 1000b = 1 0 00 : RPL=0, LDT=0, so GDT is used, offset in GDT table is (1 << 3) = 8
 +
::CS of 0x23 = 100011b = 100 0 11 : RPL=3, LDT=0 (GDT), offset in GDT table is 100b=4, (4 << 3) = 32
  
example:<br>
+
Note that even though 64-bit mode is used, bits 3 to 15 still only need to be shifted by 3 to point to the proper offset
CS of 8 = 1000b = 1 0 00 : RPL=0, LDT=0, so GDT is used, offset in GDT table is (1 << 3) = 8
 
CS of 0x23 = 100011b = 100 0 11 : RPL=3, LDT=0 (GDT), offset in GDT table is 100b=4, (4 << 3) = 32
 
  
Note that even though 64-bit mode is used, bits 3 to 15 still only need to be shifted by 3 to point to the proper offset
 
  
 
== GDT ==
 
== GDT ==
Line 26: Line 223:
  
 
Useful interrupts in regards of game hacking: Interrupt 1(Single step), 3(breakpoint),13(General protection fault) and 14 (Page fault)
 
Useful interrupts in regards of game hacking: Interrupt 1(Single step), 3(breakpoint),13(General protection fault) and 14 (Page fault)
 +
  
 
== Flags ==
 
== Flags ==
There are 32 bits available for the 17 EFlags. Missing bits in this list are not a mistake, some flags temporarily use their neighbours.<br>
+
The FLAGS register is the status register that contains the current state of the processor.
ID, VIP, VIF, AC, VM, RF, NT, IOPL, OF, DF, IF, TF, SF, ZF, AF, PF, CF<br>
+
This register is 16 bits wide.
 +
Its successors, the EFLAGS and RFLAGS registers, are 32 bits and 64 bits wide.
 +
The wider registers retain compatibility with their smaller predecessors.<small>[6]</small>
 +
 
 +
 
 +
Missing bits in this list are not a mistake, some flags temporarily use their neighbours.<small>[5]</small>
 +
<!-- ID, VIP, VIF, AC, VM, RF, NT, IOPL, OF, DF, IF, TF, SF, ZF, AF, PF, CF -->
  
 
{| class="gallery" style="background-color:#f4f4f4"
 
{| class="gallery" style="background-color:#f4f4f4"
|+ Flags
+
|+ FLAGS register
! Bit !! Flag !! Description
+
! Bit !! Flag !! Name !! Description
 
|-
 
|-
|00
+
|'''00'''
|'''CF''' Carry Flag
+
|'''CF'''
 +
|Carry Flag
 
|Becomes one if an addition, multiplication, AND, OR, etc results in a value larger than the register meant for the result.
 
|Becomes one if an addition, multiplication, AND, OR, etc results in a value larger than the register meant for the result.
 
|-
 
|-
|02
+
|'''02'''
|'''PF''' Parity Flag
+
|'''PF'''
 +
|Parity Flag
 
|Becomes 1 if the lower 8-bits of an operation contains an even number of 1 bits.
 
|Becomes 1 if the lower 8-bits of an operation contains an even number of 1 bits.
 
|-
 
|-
|04
+
|'''04'''
|'''AF''' Auxiliary Flag
+
|'''AF'''
 +
|Auxiliary Flag
 
|Set on a carry or borrow to the value of the lower order 4 bits.
 
|Set on a carry or borrow to the value of the lower order 4 bits.
 
|-
 
|-
|06
+
|'''06'''
|'''ZF''' Zero Flag
+
|'''ZF'''
 +
|Zero Flag
 
|Becomes 1 if an operation results in a 0 writeback, or 0 register.
 
|Becomes 1 if an operation results in a 0 writeback, or 0 register.
 
|-
 
|-
|07
+
|'''07'''
|'''SF''' Sign Flag
+
|'''SF'''
 +
|Sign Flag
 
|Is 1 if the value saved is negative, 0 for positive.
 
|Is 1 if the value saved is negative, 0 for positive.
 
|-
 
|-
|08
+
|'''08'''
|'''TF''' Trap Flag
+
|'''TF'''
 +
|Trap Flag
 
|Allows for the stopping of code within a segment (allows for single stepping/debugging in programming).
 
|Allows for the stopping of code within a segment (allows for single stepping/debugging in programming).
 
|-
 
|-
|09
+
|'''09'''
|'''IF''' Interrupt Flag
+
|'''IF'''
 +
|Interrupt Flag
 
|When this flag is set, the processor begins 'listening' for external interrupts.
 
|When this flag is set, the processor begins 'listening' for external interrupts.
 
|-
 
|-
|10
+
|'''10'''
|'''DF''' Direction Flag
+
|'''DF'''
 +
|Direction Flag
 
|Determines the direction to move through the code (specific to repeat instructions).
 
|Determines the direction to move through the code (specific to repeat instructions).
 
|-
 
|-
|11
+
|'''11'''
|'''OF''' Overflow Flag
+
|'''OF'''
|Becomes 1 if the operation is larger than available space to write (eg: addition which results in a number >32-bits).
+
|Overflow Flag
 +
|Becomes 1 if the operation is larger than available space to write (eg: addition which results in a number &gt; 32-bits).
 
|-
 
|-
|12-13
+
|'''12-13'''
|'''IOPL''' I/O Privilege Level
+
|'''IOPL'''
 +
|I/O Privilege Level
 
|2-bit register specifying which privilege level is required to access the IO ports
 
|2-bit register specifying which privilege level is required to access the IO ports
 
|-
 
|-
|14
+
|'''14'''
|'''NT''' Nested Task
+
|'''NT'''
 +
|Nested Task
 
|Becomes 1 when calls within a program are made.
 
|Becomes 1 when calls within a program are made.
 
|-
 
|-
|16
+
|'''16'''
|'''RF''' Resume Flag
+
|'''RF'''
 +
|Resume Flag
 
|Stays 1 upon a break, and stays that way until a given 'release' or resume operation/command occurs.
 
|Stays 1 upon a break, and stays that way until a given 'release' or resume operation/command occurs.
 
|-
 
|-
|17
+
|'''17'''
|'''VM''' Virtual Machine 8086
+
|'''VM'''
 +
|Virtual Machine 8086
 
|Becomes a 1 if the processor is to simulate the 8086 processor (16-bit).
 
|Becomes a 1 if the processor is to simulate the 8086 processor (16-bit).
 
|-
 
|-
|18
+
|'''18'''
|'''AC''' Alignment Check
+
|'''AC'''
 +
|Alignment Check
 
|Checks that a file or command is not breaking its privilege level.
 
|Checks that a file or command is not breaking its privilege level.
 
|-
 
|-
|19
+
|'''19'''
|'''VIF''' Virtual Interrupt Flag
+
|'''VIF'''
 +
|Virtual Interrupt Flag
 
|Almost always set in protected mode, listening for internal and assembling interrupts.
 
|Almost always set in protected mode, listening for internal and assembling interrupts.
 
|-
 
|-
|20
+
|'''20'''
|'''VIP''' Virtual Interrupt Pending
+
|'''VIP'''
 +
|Virtual Interrupt Pending
 
|1 if a virtual interrupt is yet to occur.
 
|1 if a virtual interrupt is yet to occur.
 
|-
 
|-
|21
+
|'''21'''
|'''ID''' ID Flag
+
|'''ID'''
 +
|ID Flag
 
|Is set if a CPU identification check is pending (used in some cases to ensure valid hardware).
 
|Is set if a CPU identification check is pending (used in some cases to ensure valid hardware).
|}
+
|}<small>[1][5]</small>
  
  
 +
The POPF, POPFD, and POPFQ instructions read from the stack the first 16, 32,
 +
and 64 bits of the flags register, respectively.
 +
POPFD was introduced with the i386 architecture and POPFQ with the x64 architecture.
 +
In 64-bit mode, PUSHF/POPF and PUSHFQ/POPFQ are available but not PUSHFD/POPFD.<small>[1]</small>
  
[http://www.tech-recipes.com/rx/1239/assembly-flags/ Source]
 
  
 
== Opcodes ==
 
== Opcodes ==
Most commonly used opcodes:
+
In computing, an opcode (abbreviated from operation code) is the portion of a machine language instruction
 +
that specifies the operation to be performed. Beside the opcode itself,
 +
most instructions also specify the data they will process, in the form of operands.<small>[8][9][10]</small>
 +
 
 +
 
 +
'''Most commonly used opcodes:'''
  
; PUSH ''operand''
+
; [[Assembler:Commands:PUSH|PUSH]] ''operand''
 
: PUSHes (saves) data onto the stack.
 
: PUSHes (saves) data onto the stack.
  
; POP ''operand''
+
; [[Assembler:Commands:POP|POP]] ''operand''
 
: POPs (clears) data from the stack.
 
: POPs (clears) data from the stack.
  
; PUSHF
+
; [[Assembler:Commands:PUSHF|PUSHF]]
: PUSHes (saves) the FLAGS register onto the stack.
+
: PUSHes (saves) the FLAGS register (16 bit) onto the stack.
 +
 
 +
; [[Assembler:Commands:POPF|POPF]]
 +
: POPs (clears) the FLAGS register (16 bit) from the stack.
 +
 
 +
; [[Assembler:Commands:PUSHFD|PUSHFD]]
 +
: PUSHes (saves) the EFLAGS register (32 bit) onto the stack.
 +
: Not available in 64 bit mode.
  
; POPF
+
; [[Assembler:Commands:POPFD|POPFD]]
: POPs (clears) the FLAGS register from the stack.
+
: POPs (clears) the EFLAGS register (32 bit) from the stack.
 +
: Not available in 64 bit mode.
  
; PUSHA
+
; [[Assembler:Commands:PUSHFQ|PUSHFQ]]
: PUSHes (saves) all general purpose registers onto stack.
+
: PUSHes (saves) the RFLAGS register (64 bit) onto the stack.
  
; POPA
+
; [[Assembler:Commands:POPFQ|POPFQ]]
: POPs (clears) all general purpose registers from stack.
+
: POPs (clears) the RFLAGS register (64 bit) from the stack.
  
; JMP ''operand''
+
; [[Assembler:Commands:JMP|JMP]] ''operand''
 
: Jumps to the given ''operand'' (address).
 
: Jumps to the given ''operand'' (address).
  
; CALL ''operand''
+
; [[Assembler:Commands:CALL|CALL]] ''operand''
 
: Calls the given ''operand'' (address or function).
 
: Calls the given ''operand'' (address or function).
 
: A RET must be hit for a CALL to work properly, best to use JMPs if unsure.
 
: A RET must be hit for a CALL to work properly, best to use JMPs if unsure.
  
; RET ''operand''
+
; [[Assembler:Commands:RET|RET]] ''operand''
: Returns from a CALL optionaly removing, ''operand'' number of, bytes from the stack.
+
: Returns from a CALL optionally removing, ''operand'' number of, bytes from the stack.
 
: This is used for POPing values passed, to the CALL, from the stack.
 
: This is used for POPing values passed, to the CALL, from the stack.
  
; MOV ''destination'', ''source''
+
; [[Assembler:Commands:MOV|MOV]] ''destination'', ''source''
 
: Sets the ''destination'' to the ''source''.
 
: Sets the ''destination'' to the ''source''.
  
; INC ''operand''
+
; [[Assembler:Commands:LEA|LEA]] ''destination'', ''source''
 +
: Load Effective Address
 +
: <code>EBX = 0x00403A40</code>
 +
: <code>lea eax, [ebx+8]</code>
 +
: <code>EAX = 0x00403A48</code>
 +
 
 +
; [[Assembler:Commands:INC|INC]] ''operand''
 
: Increases the ''operand'' by one.
 
: Increases the ''operand'' by one.
 
: <code>operand = operand + 1</code>
 
: <code>operand = operand + 1</code>
  
; DEC ''operand''
+
; [[Assembler:Commands:DEC|DEC]] ''operand''
 
: Decreases the ''operand'' by one.
 
: Decreases the ''operand'' by one.
 
: <code>operand = operand - 1</code>
 
: <code>operand = operand - 1</code>
  
; ADD ''destination'', ''source''
+
; [[Assembler:Commands:ADD|ADD]] ''destination'', ''source''
 
: Adds the ''source'' to the ''destination''.
 
: Adds the ''source'' to the ''destination''.
 
: <code>destination = destination + source</code>
 
: <code>destination = destination + source</code>
  
; SUB ''destination'', ''source''
+
; [[Assembler:Commands:SUB|SUB]] ''destination'', ''source''
 
: Subtracts the ''source'' from the ''destination''.
 
: Subtracts the ''source'' from the ''destination''.
 
: <code>destination = destination - source</code>
 
: <code>destination = destination - source</code>
  
; MUL ''operand''
+
; [[Assembler:Commands:MUL|MUL]] ''operand''
: Multiplies the ''operand'' by the data register
+
: Performs an unsigned multiplication of two operands.
: Placing the high value in the data register and the low value in the accumulator register.
+
: Multiplies the ''operand'' by the accumulator register. Placing the high value in the data register and the low value in the accumulator register.
 
: <code>AH:AL = AL * operand : byte</code>
 
: <code>AH:AL = AL * operand : byte</code>
 
: <code>DX:AX = AX * operand : WORD</code>
 
: <code>DX:AX = AX * operand : WORD</code>
 
: <code>EDX:EAX = EAX * operand : DWORD</code>
 
: <code>EDX:EAX = EAX * operand : DWORD</code>
 +
: <code>RDX:RAX = RAX * operand : QWORD</code>
  
; DIV ''operand''
+
; [[Assembler:Commands:DIV|DIV]] ''operand''
 +
: Performs an unsigned division of two operands.
 
: Divids the data register (high) and the accumulator register (low) by the ''operand''.  
 
: Divids the data register (high) and the accumulator register (low) by the ''operand''.  
 
: Placing the quotient in the accumulator register and the remainder in the data register.
 
: Placing the quotient in the accumulator register and the remainder in the data register.
: <code>AL  AH = AH:AL/operand : byte AH:AL = AX</code>
+
: <code>AL  AH = AH:AL/operand : byte</code>
 
: <code>AX  DX = DX:AX/operand : WORD</code>
 
: <code>AX  DX = DX:AX/operand : WORD</code>
 
: <code>EAX  EDX = EDX:EAX/operand : DWORD</code>
 
: <code>EAX  EDX = EDX:EAX/operand : DWORD</code>
 +
: <code>RAX  RDX = RDX:RAX/operand : QWORD</code>
  
; NOP
+
; [[Assembler:Commands:NOP|NOP]]
 
: No Operation.
 
: No Operation.
 
: Usually used when removing original code.
 
: Usually used when removing original code.
  
; OR ''destination'', ''source''
+
; [[Assembler:Commands:OR|OR]] ''destination'', ''source''
 
: The OR instruction is used for supporting logical expression by performing bitwise OR operation.  
 
: The OR instruction is used for supporting logical expression by performing bitwise OR operation.  
 
: The bitwise OR operator returns 1, if the matching bits from either or both operands are one.  
 
: The bitwise OR operator returns 1, if the matching bits from either or both operands are one.  
 
: It returns 0, if both the bits are zero.
 
: It returns 0, if both the bits are zero.
 +
: <code>destination = destination | source</code>
 
:Example:
 
:Example:
            destination:    0101
+
|            destination:    0101 |
                  source:    0011
+
|                  source:    0011 |
  ---------------------------------
+
  |-----------------------------------|
  After OR -> destination:    0111
+
  | After OR -> destination:    0111 |
  
; XOR ''destination'', ''source''
+
; [[Assembler:Commands:XOR|XOR]] ''destination'', ''source''
 
: The XOR instruction implements the bitwise XOR operation.  
 
: The XOR instruction implements the bitwise XOR operation.  
 
: The XOR operation sets the resultant bit to 1, if and only if the bits from the operands are different.  
 
: The XOR operation sets the resultant bit to 1, if and only if the bits from the operands are different.  
 
: If the bits from the operands are same (both 0 or both 1), the resultant bit is cleared to 0.
 
: If the bits from the operands are same (both 0 or both 1), the resultant bit is cleared to 0.
 +
: <code>destination = destination ^ source</code>
 
:Example:
 
:Example:
              destination:    0101
+
|              destination:    0101 |
                  source:    0011
+
|                  source:    0011 |
  ----------------------------------
+
  |------------------------------------|
  After XOR -> destination:    0110
+
  | After XOR -> destination:    0110 |
  
; AND ''destination'', ''source''
+
; [[Assembler:Commands:AND|AND]] ''destination'', ''source''
 
: The AND instruction is used for supporting logical expressions by performing bitwise AND operation.  
 
: The AND instruction is used for supporting logical expressions by performing bitwise AND operation.  
 
: The bitwise AND operation returns 1, if the matching bits from both the operands are 1, otherwise it returns 0.
 
: The bitwise AND operation returns 1, if the matching bits from both the operands are 1, otherwise it returns 0.
 +
: <code>destination = destination & source</code>
 
:Example:
 
:Example:
              destination:    0101
+
|              destination:    0101 |
                  source:    0011
+
|                  source:    0011 |
  ----------------------------------
+
  |------------------------------------|
  After AND -> destination:    0001
+
  | After AND -> destination:    0001 |
  
; TEST ''destination'', ''source''
+
; [[Assembler:Commands:TEST|TEST]] ''destination'', ''source''
 
: The TEST instruction works same as the AND operation, but unlike AND instruction, it does not change the first operand.
 
: The TEST instruction works same as the AND operation, but unlike AND instruction, it does not change the first operand.
 +
: It is useful for quick tests of a register to test it for being negative or zero.  For instance `test eax,eax` will set the Z flag if eax is zero so you can use `jz` to jump if zero or `jnz` to jump if not zero, and the sign bit so you can use `js` to jump if negative or `jns` to jump if positive or zero.
  
; NOT ''operand''
+
; [[Assembler:Commands:NOT|NOT]] ''operand''
 
: The NOT instruction implements the bitwise NOT operation.  
 
: The NOT instruction implements the bitwise NOT operation.  
 
: NOT operation reverses the bits in an operand.  
 
: NOT operation reverses the bits in an operand.  
 
: The operand could be either in a register or in the memory.
 
: The operand could be either in a register or in the memory.
 +
: <code>operand = !operand</code>
 
:Example:
 
:Example:
              operand:    0101 0011
+
|              operand:    0101 0011 |
  ----------------------------------
+
  |------------------------------------|
  After NOT -> operand:    1010 1100
+
  | After NOT -> operand:    1010 1100 |
  
; LOOP ''operand''
+
; [[Assembler:Commands:LOOP|LOOP]] ''operand''
: The LOOP instruction assumes that the ECX register contains the loop count.  
+
: The LOOP instruction assumes that the (E)CX register contains the loop count.  
: When the loop instruction is executed, the ECX register is decremented and the control jumps to the target label,  
+
: When the loop instruction is executed, the (E)CX register is decremented and the control jumps to the target label,  
: until the ECX register value, i.e., the counter reaches the value zero.  
+
: until the (E)CX register value, i.e., the counter reaches the value zero.  
 
: Used for Loop control.
 
: Used for Loop control.
 
  label(loop_start)
 
  label(loop_start)
Line 228: Line 479:
 
  // loop body
 
  // loop body
 
  LOOP loop_start
 
  LOOP loop_start
 +
 +
; [[Assembler:Commands:CMP|CMP]] ''operand1'', ''operand2''
 +
: Compares the first operand with the second operand and sets the status flags in the (E)FLAGS register according to the results.
  
  
[https://en.wikipedia.org/wiki/X86_instruction_listings source]
+
<div style="font-weight:bold;font-size:1.25em;">
 +
[[Assembler:Commands|List of all assembler commands]]
 +
</div>
  
 
== See also ==
 
== See also ==
Line 236: Line 492:
 
* [[Tutorials]]
 
* [[Tutorials]]
  
==External links==
+
== External links ==
 
* [http://www.intel.com/Assets/PDF/manual/253666.pdf Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 2A: Instruction Set Reference, A-M]  
 
* [http://www.intel.com/Assets/PDF/manual/253666.pdf Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 2A: Instruction Set Reference, A-M]  
 
* [http://www.intel.com/Assets/PDF/manual/253667.pdf Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 2B: Instruction Set Reference, N-Z]
 
* [http://www.intel.com/Assets/PDF/manual/253667.pdf Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 2B: Instruction Set Reference, N-Z]
 +
* [https://wikibooks.org/wiki/X86_Assembly wikibooks.org/wiki/X86_Assembly]
 +
* [https://wikibooks.org/wiki/X86_Assembly/X86_Instructions wikibooks.org/wiki/X86_Assembly/X86_Instructions]
 +
* [https://wikipedia.org/wiki/X86_instruction_listings wikipedia.org/wiki/X86_instruction_listings]
 +
* [https://wikibooks.org/wiki/X86_Assembly/Other_Instructions wikibooks.org/wiki/X86_Assembly/Other_Instructions]
 +
* [http://c9x.me/x86/ c9x.me/x86/]
 +
* [http://ref.x86asm.net/ ref.x86asm.net]
 +
 +
== Sources ==
 +
# [https://wikipedia.org/wiki/X86 wikipedia.org/wiki/X86]
 +
# [http://www.cs.virginia.edu/~evans/cs216/guides/x86.html www.cs.virginia.edu/~evans/cs216/guides/x86.html]
 +
# [http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-1-manual.pdf 64-ia-32-architectures-software-developer-vol-1-manual.pdf]
 +
# [https://wikipedia.org/wiki/File:Table_of_x86_Registers_svg.svg wikipedia.org/wiki/File:Table_of_x86_Registers_svg.svg]
 +
# [http://www.tech-recipes.com/rx/1239/assembly-flags/ www.tech-recipes.com/rx/1239/assembly-flags/]
 +
# [https://wikipedia.org/wiki/FLAGS_register wikipedia.org/wiki/FLAGS_register]
 +
# [https://wikipedia.org/wiki/Status_register wikipedia.org/wiki/Status_register]
 +
# [https://wikipedia.org/wiki/Opcode wikipedia.org/wiki/Opcode]
 +
# [https://wikipedia.org/wiki/X86_instruction_listings wikipedia.org/wiki/X86_instruction_listings]
 +
# [https://wikibooks.org/wiki/X86_Assembly/Other_Instructions wikibooks.org/wiki/X86_Assembly/Other_Instructions]]

Latest revision as of 02:34, 26 May 2021

Registers[edit]

16 bit[edit]

There are fourteen 16-bit registers. Four of them (AX, BX, CX, DX) are general-purpose registers (GPRs). Although each may have an additional purpose; for example, only CX can be used as a counter with the loop instruction. Each can be accessed as two separate bytes (thus BX's high byte can be accessed as BH and low byte as BL). Two pointer registers have special roles: SP (stack pointer) points to the "top" of the stack, and BP (base pointer) is often used to point at some other place in the stack, typically above the local variables (see frame pointer). The registers SI, DI, BX and BP are address registers, and may also be used for array indexing.[1]

Four segment registers (CS, DS, SS and ES) are used to form a memory address. The FLAGS register contains flags such as carry flag, overflow flag and zero flag. Finally, the instruction pointer (IP) points to the next instruction that will be fetched from memory and then executed; this register cannot be directly accessed (read or written) by a program.[1]

32 bit[edit]

With the advent of the 32-bit processor, the 16-bit general-purpose registers, base registers, index registers, instruction pointer, and FLAGS register, but not the segment registers, were expanded to 32 bits. The nomenclature represented this by prefixing an "E" (for "extended") to the register names in x86 assembly language. Thus, the AX register corresponds to the lowest 16 bits of the new 32-bit EAX register, SI corresponds to the lowest 16 bits of ESI, and so on. The general-purpose registers, base registers, and index registers can all be used as the base in addressing modes, and all of those registers except for the stack pointer can be used as the index in addressing modes.[1]

Two new segment registers (FS and GS) were added. With a greater number of registers, instructions and operands, the machine code format was expanded. To provide backward compatibility, segments with executable code can be marked as containing either 16-bit or 32-bit instructions. Special prefixes allow inclusion of 32-bit instructions in a 16-bit segment or vice versa.[1]

The 80387 processor line added eight 80-bit wide (FPU) registers: st(0) to st(7).[1]

With the Pentium III, Intel added eight 128-bit SSE floating point registers (XMM0 to XMM7).[1]

There are more 32 bit registers but this gets into some that are rarely used, and processor family specific registers.[1]

64 bit[edit]

Starting with the AMD Opteron processor, the x86 architecture extended the 32-bit registers into 64-bit registers in a way similar to how the 16 to 32-bit extension took place. An R-prefix identifies the 64-bit registers (RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, RFLAGS, RIP), and eight additional 64-bit general registers (R8-R15) were also introduced in the creation of x86-64. However, these extensions are only usable in 64-bit mode, which is one of the two modes only available in long mode.[1]

128 bit[edit]

SIMD registers XMM0–XMM15.[1]


Purpose[edit]

Although the main registers (with the exception of the instruction pointer) are "general-purpose" in the 32-bit and 64-bit versions of the instruction set and can be used for anything, it was originally envisioned that they be used for the following purposes:

  • AL/AH/AX/EAX/RAX: Accumulator
  • BL/BH/BX/EBX/RBX: Base index (for use with arrays)
  • CL/CH/CX/ECX/RCX: Counter (for use with loops and strings)
  • DL/DH/DX/EDX/RDX: Extend the precision of the accumulator (e.g. combine 32-bit EAX and EDX for 64-bit integer operations in 32-bit code)
  • SI/ESI/RSI: Source index for string operations.
  • DI/EDI/RDI: Destination index for string operations.
  • SP/ESP/RSP: Stack pointer for top address of the stack.
  • BP/EBP/RBP: Stack base pointer for holding the address of the current stack frame.
  • IP/EIP/RIP: Instruction pointer. Holds the program counter, the current instruction address.

Segment registers:

  • CS: Code
  • DS: Data
  • SS: Stack
  • ES: Extra data
  • FS: Extra data #2
  • GS: Extra data #3

No particular purposes were envisioned for the other 8 registers available only in 64-bit mode.[1]


Structure[edit]

Note: The ?PL registers are only available in 64-bit mode.[1]

Note: The ?IL registers are only available in 64-bit mode.[1]


Table of x86 Registers svg.svg.png[4]


Segments[edit]

Segment registers: CS,ES,DS,SS,FS,GS

Bits 0, 1 describe the RPL, request privilege level
Bit 2 describes if the LDT is used or not
Bits 3 to 15 contain the offset into the GDT or LDT table (when shifted left by 3)
Example:
CS of 8 = 1000b = 1 0 00 : RPL=0, LDT=0, so GDT is used, offset in GDT table is (1 << 3) = 8
CS of 0x23 = 100011b = 100 0 11 : RPL=3, LDT=0 (GDT), offset in GDT table is 100b=4, (4 << 3) = 32

Note that even though 64-bit mode is used, bits 3 to 15 still only need to be shifted by 3 to point to the proper offset


GDT[edit]

The gdt is a table of descriptors that describe what should happen when entering a specific segment and setting it's rights. (What access rights, the limits, if it's data or code, etc...)


IDT[edit]

The IDT is a table of descriptors that describe what should happen when an interrupt occurs. It contains the used code segment, and the EIP/RIP address to call, but also information like the DPL of the interrupt and if it's a callgate, taskgate or interrupt gate

Useful interrupts in regards of game hacking: Interrupt 1(Single step), 3(breakpoint),13(General protection fault) and 14 (Page fault)


Flags[edit]

The FLAGS register is the status register that contains the current state of the processor. This register is 16 bits wide. Its successors, the EFLAGS and RFLAGS registers, are 32 bits and 64 bits wide. The wider registers retain compatibility with their smaller predecessors.[6]


Missing bits in this list are not a mistake, some flags temporarily use their neighbours.[5]

[1][5]


The POPF, POPFD, and POPFQ instructions read from the stack the first 16, 32, and 64 bits of the flags register, respectively. POPFD was introduced with the i386 architecture and POPFQ with the x64 architecture. In 64-bit mode, PUSHF/POPF and PUSHFQ/POPFQ are available but not PUSHFD/POPFD.[1]


Opcodes[edit]

In computing, an opcode (abbreviated from operation code) is the portion of a machine language instruction that specifies the operation to be performed. Beside the opcode itself, most instructions also specify the data they will process, in the form of operands.[8][9][10]


Most commonly used opcodes:

PUSH operand
PUSHes (saves) data onto the stack.
POP operand
POPs (clears) data from the stack.
PUSHF
PUSHes (saves) the FLAGS register (16 bit) onto the stack.
POPF
POPs (clears) the FLAGS register (16 bit) from the stack.
PUSHFD
PUSHes (saves) the EFLAGS register (32 bit) onto the stack.
Not available in 64 bit mode.
POPFD
POPs (clears) the EFLAGS register (32 bit) from the stack.
Not available in 64 bit mode.
PUSHFQ
PUSHes (saves) the RFLAGS register (64 bit) onto the stack.
POPFQ
POPs (clears) the RFLAGS register (64 bit) from the stack.
JMP operand
Jumps to the given operand (address).
CALL operand
Calls the given operand (address or function).
A RET must be hit for a CALL to work properly, best to use JMPs if unsure.
RET operand
Returns from a CALL optionally removing, operand number of, bytes from the stack.
This is used for POPing values passed, to the CALL, from the stack.
MOV destination, source
Sets the destination to the source.
LEA destination, source
Load Effective Address
EBX = 0x00403A40
lea eax, [ebx+8]
EAX = 0x00403A48
INC operand
Increases the operand by one.
operand = operand + 1
DEC operand
Decreases the operand by one.
operand = operand - 1
ADD destination, source
Adds the source to the destination.
destination = destination + source
SUB destination, source
Subtracts the source from the destination.
destination = destination - source
MUL operand
Performs an unsigned multiplication of two operands.
Multiplies the operand by the accumulator register. Placing the high value in the data register and the low value in the accumulator register.
AH:AL = AL * operand : byte
DX:AX = AX * operand : WORD
EDX:EAX = EAX * operand : DWORD
RDX:RAX = RAX * operand : QWORD
DIV operand
Performs an unsigned division of two operands.
Divids the data register (high) and the accumulator register (low) by the operand.
Placing the quotient in the accumulator register and the remainder in the data register.
AL AH = AH:AL/operand : byte
AX DX = DX:AX/operand : WORD
EAX EDX = EDX:EAX/operand : DWORD
RAX RDX = RDX:RAX/operand : QWORD
NOP
No Operation.
Usually used when removing original code.
OR destination, source
The OR instruction is used for supporting logical expression by performing bitwise OR operation.
The bitwise OR operator returns 1, if the matching bits from either or both operands are one.
It returns 0, if both the bits are zero.
destination = destination | source
Example:
|             destination:     0101 |
|                  source:     0011 |
|-----------------------------------|
| After OR -> destination:     0111 |
XOR destination, source
The XOR instruction implements the bitwise XOR operation.
The XOR operation sets the resultant bit to 1, if and only if the bits from the operands are different.
If the bits from the operands are same (both 0 or both 1), the resultant bit is cleared to 0.
destination = destination ^ source
Example:
|              destination:     0101 |
|                   source:     0011 |
|------------------------------------|
| After XOR -> destination:     0110 |
AND destination, source
The AND instruction is used for supporting logical expressions by performing bitwise AND operation.
The bitwise AND operation returns 1, if the matching bits from both the operands are 1, otherwise it returns 0.
destination = destination & source
Example:
|              destination:     0101 |
|                   source:     0011 |
|------------------------------------|
| After AND -> destination:     0001 |
TEST destination, source
The TEST instruction works same as the AND operation, but unlike AND instruction, it does not change the first operand.
It is useful for quick tests of a register to test it for being negative or zero. For instance `test eax,eax` will set the Z flag if eax is zero so you can use `jz` to jump if zero or `jnz` to jump if not zero, and the sign bit so you can use `js` to jump if negative or `jns` to jump if positive or zero.
NOT operand
The NOT instruction implements the bitwise NOT operation.
NOT operation reverses the bits in an operand.
The operand could be either in a register or in the memory.
operand = !operand
Example:
|              operand:    0101 0011 |
|------------------------------------|
| After NOT -> operand:    1010 1100 |
LOOP operand
The LOOP instruction assumes that the (E)CX register contains the loop count.
When the loop instruction is executed, the (E)CX register is decremented and the control jumps to the target label,
until the (E)CX register value, i.e., the counter reaches the value zero.
Used for Loop control.
label(loop_start)
MOV ECX,10
loop_start:
// loop body
LOOP loop_start
CMP operand1, operand2
Compares the first operand with the second operand and sets the status flags in the (E)FLAGS register according to the results.


List of all assembler commands

See also[edit]

External links[edit]

Sources[edit]

  1. wikipedia.org/wiki/X86
  2. www.cs.virginia.edu/~evans/cs216/guides/x86.html
  3. 64-ia-32-architectures-software-developer-vol-1-manual.pdf
  4. wikipedia.org/wiki/File:Table_of_x86_Registers_svg.svg
  5. www.tech-recipes.com/rx/1239/assembly-flags/
  6. wikipedia.org/wiki/FLAGS_register
  7. wikipedia.org/wiki/Status_register
  8. wikipedia.org/wiki/Opcode
  9. wikipedia.org/wiki/X86_instruction_listings
  10. wikibooks.org/wiki/X86_Assembly/Other_Instructions]