From 8efd4f8a43e8467db717d4c8616437d4bcbe6053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Sat, 22 Jun 2019 00:00:03 +0000 Subject: [PATCH] x86 asm: move most of registers from x86-assembly-cheat --- README.adoc | 50 ++++++++++++++++++++++++++-- userland/arch/x86_64/registers.S | 56 ++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 userland/arch/x86_64/registers.S diff --git a/README.adoc b/README.adoc index 7eaa00b..2ad9cae 100644 --- a/README.adoc +++ b/README.adoc @@ -11847,6 +11847,7 @@ Other infrastructure sanity checks that you might want to look into include: After seeing an <>, you need to learn the general registers: +* x86: <> * arm ** link:userland/arch/arm/registers.S[] * aarch64 @@ -12354,6 +12355,45 @@ Applications: http://stackoverflow.com/questions/234906/whats-the-purpose-of-the Arch agnostic infrastructure getting started at: <>. +=== x86 registers + +link:userland/arch/x86_64/registers.S + +.... +|-----------------------------------------------| +| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +|-----------------------------------------------| +| | | AH | AL | +|-----------------------------------------------| +| | | AX | +|-----------------------------------------------| +| | EAX | +|-----------------------------------------------| +| RAX | +|-----------------------------------------------| +.... + +For the newer x86_64 registers, the naming convention is somewhat saner: + +.... +|-----------------------------------------------| +| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +|-----------------------------------------------| +| | |R12H |R12L | +|-----------------------------------------------| +| | | R12W | +|-----------------------------------------------| +| | R12D | +|-----------------------------------------------| +| R12 | +|-----------------------------------------------| +.... + +Most of the 8 older x86 general purpose registers are not "really" general purpose in the sense that a few instructions magically use them without an explicit encoding. This is reflected in their names: + +* RAX: Accumulator. The general place where you add, subtract and otherwise manipulate results in-place. Magic for example for <> +* RCX, RSI, RDI: Counter, Source and Destination. Used in <> + === x86 addressing modes Example: link:userland/arch/x86_64/address_modes.S[] @@ -12631,7 +12671,7 @@ These instructions do some operation on an array item, and automatically update ** link:userland/arch/x86_64/movs.S[]: MOVS: MOV String: move from one memory to another with addresses given by RSI and RDI. Could be used to implement `memmov`. ** link:userland/arch/x86_64/scas.S[]: SCAS: SCan String: compare memory to the value in a register. Could be used to implement `strchr`. -The RSI and RDI registers are actually named after these intructions! S is the source of string instructions, D is the destination of string instructions. +The RSI and RDI registers are actually named after these intructions! S is the source of string instructions, D is the destination of string instructions: https://stackoverflow.com/questions/1856320/purpose-of-esi-edi-registers The direction of the index increment depends on the direction flag of the FLAGS register: 0 means forward and 1 means backward: https://stackoverflow.com/questions/9636691/what-are-cld-and-std-for-in-x86-assembly-language-what-does-df-do @@ -15402,11 +15442,17 @@ which also downloads build dependencies. Then the following times just to the faster: .... -./build-docs +./build-doc .... Source: link:build-doc[] +Then just open the HTML output at: + +.... +xdg-open out/README.html +.... + [[documentation-verification]] ==== Documentation verification diff --git a/userland/arch/x86_64/registers.S b/userland/arch/x86_64/registers.S new file mode 100644 index 0000000..258a602 --- /dev/null +++ b/userland/arch/x86_64/registers.S @@ -0,0 +1,56 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#x86-registers */ + +#include + +LKMC_PROLOGUE + /* All the 16 general purpose registers. */ + mov $0x0, %rax + mov $0x0, %rcx + mov $0x0, %rdx + mov $0x0, %rbx +#if 0 + /* We don't want to do touch those because if affets our main call stack. */ + mov $0x0, %rbp + mov $0x0, %rsp +#endif + mov $0x0, %rsi + mov $0x0, %rdi + mov $0x0, %r8 + mov $0x0, %r9 + mov $0x0, %r10 + mov $0x0, %r11 + mov $0x0, %r12 + mov $0x0, %r13 + mov $0x0, %r14 + mov $0x0, %r15 + + /* EAX and AX. */ + mov $0x11111111, %eax + mov $0x2222, %ax + LKMC_ASSERT_EQ_32(%eax, $0x11112222) + + /* EAX, AL and AH. */ + mov $0x11111111, %eax + mov $0x22, %ah + mov $0x33, %al + LKMC_ASSERT_EQ_32(%eax, $0x11112233) + + /* R12D, R12W and R12B */ + mov $0x11111111, %r12d + mov $0x2222, %r12w + mov $0x33, %r12b + LKMC_ASSERT_EQ_32(%r12d, $0x11112233) + +#if 0 + /* There is no R12H: the second byte is only addressable on the old registers. + * Error: bad register name `%r12h' */ + mov $0x22, %r12h +#endif + + /* Keep in mind that most 32-bit register instructions zero out the top bits of RAX! + * https://stackoverflow.com/questions/11177137/why-do-x86-64-instructions-on-32-bit-registers-zero-the-upper-part-of-the-full-6 */ + mov $0x1122334455667788, %r12 + LKMC_ASSERT_EQ_32(%r12d, $0x55667788) + mov $0x99AABBCC, %r12 + LKMC_ASSERT_EQ(%r12, $0x0000000099AABBCC) +LKMC_EPILOGUE