aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorjohannst <johannes.stoelp@gmail.com>2021-06-21 00:11:23 +0200
committerjohannst <johannes.stoelp@gmail.com>2021-06-21 00:11:23 +0200
commit97c6252800e020af05f0e0d7afc037c04753bc83 (patch)
tree8329d7a33eb2a258bcc3a7548edfe15ec6c3e947
parente40bb4ba54f2c4bd5e8ca56bb22932773a57ec9d (diff)
downloadnotes-97c6252800e020af05f0e0d7afc037c04753bc83.tar.gz
notes-97c6252800e020af05f0e0d7afc037c04753bc83.zip
x86_64: add string operations + more flags details
-rw-r--r--src/arch/x86_64.md108
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]