2022-11-13 22:38:01 +01:00
# amd64 instructions
2023-08-23 23:23:45 +02:00
This pages lists and describes basic instructions used in amd64 and x86 assembly language.
Please take a look at [the intel 64 instruction reference book ](https://cdrdv2.intel.com/v1/dl/getContent/671110 )the instruction set as well as the [registers supported ](https://cdrdv2.intel.com/v1/dl/getContent/671098 ) is growing further with every CPU generation. The reference book is currently 2522 pages strong.
2022-11-13 22:38:01 +01:00
* `;` starts a comment
2023-08-23 23:23:45 +02:00
## Operands
Three types of operands are used in amd64/x86 assembly
* __Immediate__, numbers (e.g. `0xDEADBEEF` )
* __register__, existing registers (e.g. `rbx` )
* __memory__, memory addresses in brackets (e.g. `[0xFF]` )
2022-11-13 22:38:01 +01:00
## Move
2023-08-23 23:23:45 +02:00
Basic instructions to used to move values are the following
* `MOV` , from source to destination, exception: no mem to mem movement allowed
* `LEA` , loads memory address and stores it in the destination. Addresses can have an offset. Does not dereference `[var]` or `[var+x]`
* `PUSH` & `POP` , put & retrieve registers to/from stack. `
* PUSHA` puts all 16 bit general purpose registers, `PUSHAD` puts all 32 registers onto the stack
* `POPA` retrieve all 16 bit general purpose registers, `POPAD` retrieve all 32 registers from the stack
2022-11-13 22:38:01 +01:00
## Arithmetic
2023-08-23 23:23:45 +02:00
Basic arithmetics are the following
* `INC` , increment by 1
* `DEC` , decrement by 1
* `ADD` , result is stored in dest
* `SUB` , substracts source from dest and stores in dest, ZF is set if result is zero, CF is set if result is lower than the substracted value
* `MUL` & `IMUL` , result may be stored in upper and lower halfs (rdx:rax) because of resulting size of the product
2022-11-13 22:38:01 +01:00
* `DIV` & `IDIV` , rax is divided by rbx and may be stored in two halfs as well
2023-08-23 23:23:45 +02:00
* `SHR` & `SHL` , shifts bits from dest times the count `n` of source right or left, respectively (`2^n`). Uses carry flag (CF) for overflow.
* `ROR` & `ROL` , shifts bits from dest times the count `n` of source right or left, respectively. Does not use CF but appends the value on the other end of the value, like a ring structure.
## Boolean
Boolean instructions on binary numbers
* `AND` , stores result in dest
* `OR` , stores result in dest
* `NOT` , for example is used to flip ones and zeros of a value
* `XOR` , for example is used to zero the value of a register by XORing it with itself
## Frame Basics
2022-11-13 22:38:01 +01:00
* `RET` , return value to the caller
* `CMP` , compare two values and sets flag. Next instruction is a jump condition to a line number. Works as follows
* `JE` , `JEZ` , `JLE` ... followed by linenumber
2023-08-23 23:23:45 +02:00
* `NOP` , `\x90` operates nothing, but the duration is exactly a single instructions
* `CALL` a function, prepare function prologue, save `EBP` and `ESP` of the frame in before hand
2022-11-13 22:38:01 +01:00
## Address Handling
2023-08-23 23:23:45 +02:00
A value with brackets around it like `[var]` is a reference to memory address at `var` .
If var contains an address then after `mov [var], 42` var points to the value 42. `[` dereference.
2022-11-13 22:38:01 +01:00
## Zero Handling in Registers
2023-08-23 23:23:45 +02:00
2022-11-13 22:38:01 +01:00
* Move to `eax` will result in zeroing the upper 32 bit of an `rax` register, move to `ax` , `ah` , `al` will not.
* `MOVZX` zeros anything but the value moved to the register inside of it.
2023-08-23 23:23:45 +02:00
## Conditionals
Test uses just the flag register's ZF to store the status of the result, it executes an `ADD` on the values
* `TEST` (ZF=0) if result is 0
Compare instruction `CMP` is used to set the following flags, it executes a `SUB` on the values
* `CMP` (ZF=1 and PF=1) if dest and source values are equal
* `CMP` (CF=1 and SF=1) if source is greater than dest
* `CMP` (ZF=0 and CF=0) if dest is greater than source
For signed value comparison the following instructions are available
* `JZ` (ZF=1)
* `JNZ` (ZF=0)
* `JE` and `JEZ` are used after `CMP`
2022-11-13 22:38:01 +01:00
2023-08-23 23:23:45 +02:00
* `JL/JNGE` (SF < > OF) ; Jump if less/not greater or equal
* `JGE/JNL` (SF = OF) ; Jump if greater or equal/not less
* `JLE/JNG` (ZF = 1 or SF < > OF); Jump if less or equal/not greater
* `JG/JNLE` (ZF = 0 and SF = OF); Jump if greater/not less or equal
For unsigned value comparison the following instructions are available
* `JB/JNAE` (CF = 1) ; Jump if below/not above or equal
* `JAE/JNB` (CF = 0) ; Jump if above or equal/not below
* `JBE/JNA` (CF = 1 or ZF = 1) ; Jump if below or equal/not above
* `JA/JNBE` (CF = 0 and ZF = 0); Jump if above/not below or equal
2022-11-13 22:38:01 +01:00
## Flags
2023-08-23 23:23:45 +02:00
Resulting status of other registers is stored in the flag register.
2022-11-13 22:38:01 +01:00
* `eflags` 32bit
* `rflags` 64bit
### Status
2023-08-23 23:23:45 +02:00
* __Zero Flag__ (ZF), 1 if the result of the comparison is equal
* __Carry Flag__ (CF), a 1 is stored if a carry is needed after a calculation
* __Overflow Flag__ (OF), a register overflow results in a 1
* __Sign Flag__ (SF), 1 if result is negative
* __Adjust/Auxiliary Flag__ (AF), carry flag for BCD
* __Parity Flag__ (PF), 1 if the last 8 bits are even
2022-11-13 22:38:01 +01:00
* __Trap Flag__ (TF)
2023-08-23 23:23:45 +02:00
* __Direction__ (DF) A string is processed backwards if 1, forward if 0
* __Interrupt Enable__ (IF), hardware interrupt is enabled if 1, disabled if 0
2022-11-13 22:38:01 +01:00
2023-08-23 23:23:45 +02:00
## Calling Conventions
2022-11-13 22:38:01 +01:00
## cdecl
2023-08-23 23:23:45 +02:00
`#TBD`
2022-11-13 22:38:01 +01:00
## fastcall
2023-08-23 23:23:45 +02:00
2022-11-13 22:38:01 +01:00
* First four are passed __left to right__
* int -> RCX, RDX, R8, R9
* float -> XMM0, XMM1, XMM2, XMM3
* Rest is __right to left__
* Basepointer is saved by the caller
* Return values is passes via `rax` or `xmm0`
* Caller allocates space for at least four values, so 32 bytes are reserved. `$rsp to $rsp+0x18`
* Volatile registers are `rax, rcx, r8, r9, r10, r11, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5` . These are destroyed after function call.
* Nonvolatile registers are `rbx, rbp, rdi, rsi, rsp, r12, r13, r14, r15, xmm6-15` ares saved and restored after function call.