diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/x86_64.md | 108 |
1 files changed, 88 insertions, 20 deletions
diff --git a/src/arch/x86_64.md b/src/arch/x86_64.md index 5498569..6343cce 100644 --- a/src/arch/x86_64.md +++ b/src/arch/x86_64.md @@ -37,40 +37,108 @@ rip eip ip instruction pointer ```markdown rflags -bits desc ------------------------------ -[11] OF overflow flag -[10] DF direction flag - [7] SF sign flag - [6] ZF zero flag - [4] AF auxiliary carry flag - [2] PF parity flag - [0] CF carry flag +bits desc instr comment +-------------------------------------------------------------------------------------------------------------- + [21] ID identification ability to set/clear -> indicates support for CPUID instr + [18] AC alignment check alignment exception for PL 3 (user), requires CR0.AM +[13:12] IOPL io privilege level + [11] OF overflow flag + [10] DF direction flag cld/std + [9] IF interrupt enable cli/sti + [7] SF sign flag + [6] ZF zero flag + [4] AF auxiliary carry flag + [2] PF parity flag + [0] CF carry flag +``` + +Change flag bits with `pushf` / `popf` instructions: +```x86asm +pushfd // push flags (4bytes) onto stack +or dword ptr [esp], (1 << 18) // enable AC flag +popfd // pop flags (4byte) from stack +``` +> There is also `pushfq` / `popfq` to push and pop all 8 bytes of `rflags`. + +### Model Specific Register (MSR) +```x86asm +rdmsr // Read MSR register, effectively does EDX:EAX <- MSR[ECX] +wrmsr // Write MSR register, effectively does MSR[ECX] <- EDX:EAX +``` + +## Size directives +Explicitly specify size of the operation. +```x86asm +mov byte ptr [rax], 0xff // save 1 byte(s) at [rax] +mov word ptr [rax], 0xff // save 2 byte(s) at [rax] +mov dword ptr [rax], 0xff // save 4 byte(s) at [rax] +mov qword ptr [rax], 0xff // save 8 byte(s) at [rax] ``` ## Addressing -```asm -movw [rax], rbx // save val in rbx at [rax] -movw [imm], rbx // save val in rbx at [imm] -movw rax, [rbx+4*rcx] // load val at [rbx+4*rcx] into rax +```x86asm +mov qword ptr [rax], rbx // save val in rbx at [rax] +mov qword ptr [imm], rbx // save val in rbx at [imm] +mov rax, qword ptr [rbx+4*rcx] // load val at [rbx+4*rcx] into rax ``` `rip` relative addressing: -```asm +```x86asm lea rax, [rip+.my_str] // load addr of .my_str into rax ... .my_str: .asciz "Foo" ``` -## Size directives -Explicitly specify size of the operation. +## String instructions +The operand size of a string instruction is defined by the instruction suffix +`b | w | d | q`. + +Source and destination registers are modified according to the `direction flag +(DF)` in the `flags` register +- `DF=0` increment src/dest registers +- `DF=1` decrement src/dest registers +Following explanation assumes `byte` operands with `DF=0`: ```x86asm -mov byte ptr [rax], 0xff // save 1 byte(s) at [rax] -mov word ptr [rax], 0xff // save 2 byte(s) at [rax] -mov dword ptr [rax], 0xff // save 4 byte(s) at [rax] -mov qword ptr [rax], 0xff // save 8 byte(s) at [rax] +movsb // move data from string to string + // ES:[DI] <- DS:[SI] + // DI <- DI + 1 + // SI <- SI + 1 + +lodsb // load string + // AL <- DS:[SI] + // SI <- SI + 1 + +stosb // store string + // ES:[DI] <- AL + // DI <- DI + 1 + +cmpsb // compare string operands + // DS:[SI] - ES:[DI] ; set status flag (eg ZF) + // SI <- SI + 1 + // DI <- DI + 1 + +scasb // scan string + // AL - ES:[DI] ; set status flag (eg ZF) + // DI <- DI + 1 +``` + +String operations can be repeated: +```x86asm +rep // repeat until rcx = 0 +repz // repeat until rcx = 0 or while ZF = 0 +repnz // repeat until rcx = 0 or while ZF = 1 +``` + +### Example: Simple `memset` +```x86asm +// memset (dest, 0xaa /* char */, 0x10 /* len */) + +lea di, [dest] +mov al, 0xaa +mov cx, 0x10 +rep stosb ``` ## [SysV x86_64 ABI][sysvabi] |