x86 asm: move stack instructions in from x86-assembly-cheat

This commit is contained in:
Ciro Santilli 六四事件 法轮功
2019-06-23 00:00:00 +00:00
parent 8efd4f8a43
commit 9917b0e4d9
6 changed files with 214 additions and 3 deletions

View 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

View File

@@ -19,4 +19,4 @@ asm_main_after_prologue:
syscall
msg:
.ascii "hello\n"
len = . - msg
len = . - msg

View 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

View 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

View 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