Skip to content

Commit 8efd4f8

Browse files
committed
x86 asm: move most of registers from x86-assembly-cheat
1 parent fd5b62e commit 8efd4f8

File tree

2 files changed

+104
-2
lines changed

2 files changed

+104
-2
lines changed

README.adoc

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11847,6 +11847,7 @@ Other infrastructure sanity checks that you might want to look into include:
1184711847

1184811848
After seeing an <<userland-assembly,ADD hello world>>, you need to learn the general registers:
1184911849

11850+
* x86: <<x86-registers>>
1185011851
* arm
1185111852
** link:userland/arch/arm/registers.S[]
1185211853
* aarch64
@@ -12354,6 +12355,45 @@ Applications: http://stackoverflow.com/questions/234906/whats-the-purpose-of-the
1235412355

1235512356
Arch agnostic infrastructure getting started at: <<userland-assembly>>.
1235612357

12358+
=== x86 registers
12359+
12360+
link:userland/arch/x86_64/registers.S
12361+
12362+
....
12363+
|-----------------------------------------------|
12364+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
12365+
|-----------------------------------------------|
12366+
| | | AH | AL |
12367+
|-----------------------------------------------|
12368+
| | | AX |
12369+
|-----------------------------------------------|
12370+
| | EAX |
12371+
|-----------------------------------------------|
12372+
| RAX |
12373+
|-----------------------------------------------|
12374+
....
12375+
12376+
For the newer x86_64 registers, the naming convention is somewhat saner:
12377+
12378+
....
12379+
|-----------------------------------------------|
12380+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
12381+
|-----------------------------------------------|
12382+
| | |R12H |R12L |
12383+
|-----------------------------------------------|
12384+
| | | R12W |
12385+
|-----------------------------------------------|
12386+
| | R12D |
12387+
|-----------------------------------------------|
12388+
| R12 |
12389+
|-----------------------------------------------|
12390+
....
12391+
12392+
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:
12393+
12394+
* RAX: Accumulator. The general place where you add, subtract and otherwise manipulate results in-place. Magic for example for <<MUL,x86 binary arithmetic instructions>>
12395+
* RCX, RSI, RDI: Counter, Source and Destination. Used in <<x86-string-instructions>>
12396+
1235712397
=== x86 addressing modes
1235812398

1235912399
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
1263112671
** 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`.
1263212672
** link:userland/arch/x86_64/scas.S[]: SCAS: SCan String: compare memory to the value in a register. Could be used to implement `strchr`.
1263312673

12634-
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.
12674+
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
1263512675

1263612676
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
1263712677

@@ -15402,11 +15442,17 @@ which also downloads build dependencies.
1540215442
Then the following times just to the faster:
1540315443

1540415444
....
15405-
./build-docs
15445+
./build-doc
1540615446
....
1540715447

1540815448
Source: link:build-doc[]
1540915449

15450+
Then just open the HTML output at:
15451+
15452+
....
15453+
xdg-open out/README.html
15454+
....
15455+
1541015456
[[documentation-verification]]
1541115457
==== Documentation verification
1541215458

userland/arch/x86_64/registers.S

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* https://github.com/cirosantilli/linux-kernel-module-cheat#x86-registers */
2+
3+
#include <lkmc.h>
4+
5+
LKMC_PROLOGUE
6+
/* All the 16 general purpose registers. */
7+
mov $0x0, %rax
8+
mov $0x0, %rcx
9+
mov $0x0, %rdx
10+
mov $0x0, %rbx
11+
#if 0
12+
/* We don't want to do touch those because if affets our main call stack. */
13+
mov $0x0, %rbp
14+
mov $0x0, %rsp
15+
#endif
16+
mov $0x0, %rsi
17+
mov $0x0, %rdi
18+
mov $0x0, %r8
19+
mov $0x0, %r9
20+
mov $0x0, %r10
21+
mov $0x0, %r11
22+
mov $0x0, %r12
23+
mov $0x0, %r13
24+
mov $0x0, %r14
25+
mov $0x0, %r15
26+
27+
/* EAX and AX. */
28+
mov $0x11111111, %eax
29+
mov $0x2222, %ax
30+
LKMC_ASSERT_EQ_32(%eax, $0x11112222)
31+
32+
/* EAX, AL and AH. */
33+
mov $0x11111111, %eax
34+
mov $0x22, %ah
35+
mov $0x33, %al
36+
LKMC_ASSERT_EQ_32(%eax, $0x11112233)
37+
38+
/* R12D, R12W and R12B */
39+
mov $0x11111111, %r12d
40+
mov $0x2222, %r12w
41+
mov $0x33, %r12b
42+
LKMC_ASSERT_EQ_32(%r12d, $0x11112233)
43+
44+
#if 0
45+
/* There is no R12H: the second byte is only addressable on the old registers.
46+
* Error: bad register name `%r12h' */
47+
mov $0x22, %r12h
48+
#endif
49+
50+
/* Keep in mind that most 32-bit register instructions zero out the top bits of RAX!
51+
* https://stackoverflow.com/questions/11177137/why-do-x86-64-instructions-on-32-bit-registers-zero-the-upper-part-of-the-full-6 */
52+
mov $0x1122334455667788, %r12
53+
LKMC_ASSERT_EQ_32(%r12d, $0x55667788)
54+
mov $0x99AABBCC, %r12
55+
LKMC_ASSERT_EQ(%r12, $0x0000000099AABBCC)
56+
LKMC_EPILOGUE

0 commit comments

Comments
 (0)