mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
x86 asm: move stack instructions in from x86-assembly-cheat
This commit is contained in:
23
userland/arch/x86_64/enter.S
Normal file
23
userland/arch/x86_64/enter.S
Normal file
@@ -0,0 +1,23 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#x86-enter-and-leave-instructions */
|
||||
|
||||
#include <lkmc.h>
|
||||
|
||||
LKMC_PROLOGUE
|
||||
/* Save values of interest before enter. */
|
||||
mov %rbp, %r12
|
||||
mov %rsp, %r13
|
||||
enter $16, $0
|
||||
mov %rsp, %r14
|
||||
|
||||
/* Restore stack so that we can do our assertions. */
|
||||
add $16, %rsp
|
||||
leave
|
||||
|
||||
/* ENTER pushed the stack down 24 bytes:
|
||||
*
|
||||
* * 8 due to `push %rbp` that `enter` does automatically
|
||||
* * 16 due to `enter $16`
|
||||
*/
|
||||
sub %r14, %r13
|
||||
LKMC_ASSERT_EQ(%r13, $24)
|
||||
LKMC_EPILOGUE
|
||||
@@ -19,4 +19,4 @@ asm_main_after_prologue:
|
||||
syscall
|
||||
msg:
|
||||
.ascii "hello\n"
|
||||
len = . - msg
|
||||
len = . - msg
|
||||
|
||||
26
userland/arch/x86_64/freestanding/linux/int_system_call.S
Normal file
26
userland/arch/x86_64/freestanding/linux/int_system_call.S
Normal file
@@ -0,0 +1,26 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#linux-system-calls
|
||||
*
|
||||
* int $0x80 sycalls are still supported by x86_64 for some kind of backwards compatibility,
|
||||
* (TODO so when x86_64 started it didn't have SYSCALL?) althoug you should prefre
|
||||
* SYSCALL / VSDO.
|
||||
*
|
||||
* https://stackoverflow.com/questions/29440225/in-linux-x86-64-are-syscalls-and-int-0x80-related
|
||||
*/
|
||||
|
||||
.text
|
||||
.global _start
|
||||
_start:
|
||||
/* write */
|
||||
mov $4, %rax
|
||||
mov $1, %rbx
|
||||
lea msg(%rip), %rcx
|
||||
mov $len, %rdx
|
||||
int $0x80
|
||||
|
||||
/* exit */
|
||||
mov $1, %rax
|
||||
mov $0, %rbx
|
||||
int $0x80
|
||||
msg:
|
||||
.ascii "hello\n"
|
||||
len = . - msg
|
||||
45
userland/arch/x86_64/push.S
Normal file
45
userland/arch/x86_64/push.S
Normal file
@@ -0,0 +1,45 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#x86-push-and-pop-instructions */
|
||||
|
||||
#include <lkmc.h>
|
||||
|
||||
LKMC_PROLOGUE
|
||||
/* register hello world. */
|
||||
mov %rsp, %r12
|
||||
mov $0x123456789ABCDEF0, %rax
|
||||
push %rax
|
||||
/* Save the stack delta. */
|
||||
sub %rsp, %r12
|
||||
/* Save the stack value. */
|
||||
mov (%rsp), %r13
|
||||
/* Restore the stack and save its value to R14. */
|
||||
pop %r14
|
||||
/* The stack still goes down by 8 even though we pushed a 4-byte immediate. */
|
||||
LKMC_ASSERT_EQ(%r12, $8)
|
||||
LKMC_ASSERT_EQ(%r13, $0x123456789ABCDEF0)
|
||||
LKMC_ASSERT_EQ(%r14, $0x123456789ABCDEF0)
|
||||
|
||||
/* Immediate. Can only push up to 4 byte immediates. */
|
||||
mov %rsp, %r12
|
||||
push $0x12345678
|
||||
sub %rsp, %r12
|
||||
mov (%rsp), %r13
|
||||
pop %r14
|
||||
/* The stack still goes down by 8 even though we pushed a 4-byte immediate. */
|
||||
LKMC_ASSERT_EQ(%r12, $8)
|
||||
LKMC_ASSERT_EQ(%r13, $0x12345678)
|
||||
LKMC_ASSERT_EQ(%r14, $0x12345678)
|
||||
|
||||
/* Word example. */
|
||||
mov %rsp, %r12
|
||||
mov $0x1234, %ax
|
||||
push %ax
|
||||
sub %rsp, %r12
|
||||
mov $0, %r13
|
||||
mov (%rsp), %r13w
|
||||
mov $0, %r14
|
||||
pop %r14w
|
||||
/* The stack was decremented only by 2 as expected. */
|
||||
LKMC_ASSERT_EQ(%r12, $2)
|
||||
LKMC_ASSERT_EQ(%r13, $0x1234)
|
||||
LKMC_ASSERT_EQ(%r14, $0x1234)
|
||||
LKMC_EPILOGUE
|
||||
57
userland/arch/x86_64/pushf.S
Normal file
57
userland/arch/x86_64/pushf.S
Normal file
@@ -0,0 +1,57 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#x86-data-transfer-instructions */
|
||||
|
||||
#include <lkmc.h>
|
||||
|
||||
LKMC_PROLOGUE
|
||||
/* First example. */
|
||||
|
||||
/* Clear carry flag. */
|
||||
clc
|
||||
/* Save RSP before PUSHF. */
|
||||
mov %rsp, %r12
|
||||
pushf
|
||||
/* Save stack value after PUSHF. Should contain the original FLAGS. */
|
||||
mov (%rsp), %r13
|
||||
/* Re-align stack to 16-bits for our asserts. */
|
||||
sub $8, %rsp
|
||||
|
||||
/* The stack went down by 16: 8 from PUSHF, 8 from our SUB. */
|
||||
sub %rsp, %r12
|
||||
LKMC_ASSERT_EQ(%r12, $16)
|
||||
|
||||
/* Check that bit 0 (Carry Flag) of R13 is clear. */
|
||||
bt $0, %r13
|
||||
LKMC_ASSERT(jnc)
|
||||
|
||||
/* Restore the stack. */
|
||||
add $16, %rsp
|
||||
|
||||
/* Now let's set carry flag instead. */
|
||||
stc
|
||||
pushf
|
||||
mov (%rsp), %r13
|
||||
sub $8, %rsp
|
||||
bt $0, %r13
|
||||
/* Assert that it was pushed to stack set. */
|
||||
LKMC_ASSERT(jc)
|
||||
add $16, %rsp
|
||||
|
||||
/* POPF pops the stack into flags of course. */
|
||||
clc
|
||||
pushf
|
||||
stc
|
||||
popf
|
||||
LKMC_ASSERT(jnc)
|
||||
|
||||
/* PUSHFQ has the same opcode as PUSHF in the Intel manual.
|
||||
* which mentions that PUSHF can be requested with a prefix.
|
||||
*
|
||||
* GNU GAS 2.32 emits the same PUSHFQ code for both by default.
|
||||
* according to objdump.
|
||||
*/
|
||||
clc
|
||||
pushf
|
||||
stc
|
||||
popf
|
||||
LKMC_ASSERT(jnc)
|
||||
LKMC_EPILOGUE
|
||||
Reference in New Issue
Block a user