mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-27 20:14:27 +01:00
userland: add assembly support
Move arm assembly cheat here, and start some work on x86 cheat as well.
This commit is contained in:
17
userland/arch/arm/c/add.c
Normal file
17
userland/arch/arm/c/add.c
Normal file
@@ -0,0 +1,17 @@
|
||||
/* 1 + 2 == 3 */
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
int main(void) {
|
||||
uint32_t in0 = 1, in1 = 2, out;
|
||||
__asm__ (
|
||||
"add %[out], %[in0], %[in1];"
|
||||
: [out] "=r" (out)
|
||||
: [in0] "r" (in0),
|
||||
[in1] "r" (in1)
|
||||
);
|
||||
assert(in0 == 1);
|
||||
assert(in1 == 2);
|
||||
assert(out == 3);
|
||||
}
|
||||
1
userland/arch/arm/c/build
Symbolic link
1
userland/arch/arm/c/build
Symbolic link
@@ -0,0 +1 @@
|
||||
../build
|
||||
1
userland/arch/arm/c/freestanding/build
Symbolic link
1
userland/arch/arm/c/freestanding/build
Symbolic link
@@ -0,0 +1 @@
|
||||
../build
|
||||
35
userland/arch/arm/c/freestanding/hello.c
Normal file
35
userland/arch/arm/c/freestanding/hello.c
Normal file
@@ -0,0 +1,35 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
void _start(void) {
|
||||
uint32_t exit_status;
|
||||
|
||||
/* write */
|
||||
{
|
||||
char msg[] = "hello\n";
|
||||
uint32_t syscall_return;
|
||||
register uint32_t r0 __asm__ ("r0") = 1; /* stdout */
|
||||
register char *r1 __asm__ ("r1") = msg;
|
||||
register uint32_t r2 __asm__ ("r2") = sizeof(msg);
|
||||
register uint32_t r8 __asm__ ("r7") = 4; /* syscall number */
|
||||
__asm__ __volatile__ (
|
||||
"svc 0;"
|
||||
: "+r" (r0)
|
||||
: "r" (r1), "r" (r2), "r" (r8)
|
||||
: "memory"
|
||||
);
|
||||
syscall_return = r0;
|
||||
exit_status = (syscall_return != sizeof(msg));
|
||||
}
|
||||
|
||||
/* exit */
|
||||
{
|
||||
register uint32_t r0 __asm__ ("r0") = exit_status;
|
||||
register uint32_t r7 __asm__ ("r7") = 1;
|
||||
__asm__ __volatile__ (
|
||||
"svc 0;"
|
||||
: "+r" (r0)
|
||||
: "r" (r7)
|
||||
:
|
||||
);
|
||||
}
|
||||
}
|
||||
15
userland/arch/arm/c/inc.c
Normal file
15
userland/arch/arm/c/inc.c
Normal file
@@ -0,0 +1,15 @@
|
||||
/* Increment a variable in inline assembly. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
int main(void) {
|
||||
uint32_t my_local_var = 1;
|
||||
__asm__ (
|
||||
"add %[my_local_var], %[my_local_var], #1;"
|
||||
: [my_local_var] "+r" (my_local_var)
|
||||
:
|
||||
:
|
||||
);
|
||||
assert(my_local_var == 2);
|
||||
}
|
||||
28
userland/arch/arm/c/inc_float.c
Normal file
28
userland/arch/arm/c/inc_float.c
Normal file
@@ -0,0 +1,28 @@
|
||||
/* https://stackoverflow.com/questions/53960240/armv8-floating-point-output-inline-assembly */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
int main(void) {
|
||||
float my_float = 1.5;
|
||||
__asm__ (
|
||||
"vmov s0, 1.0;"
|
||||
"vadd.f32 %[my_float], %[my_float], s0;"
|
||||
: [my_float] "+t" (my_float)
|
||||
:
|
||||
: "s0"
|
||||
);
|
||||
assert(my_float == 2.5);
|
||||
|
||||
/* Undocumented %P
|
||||
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89482
|
||||
*/
|
||||
double my_double = 1.5;
|
||||
__asm__ (
|
||||
"vmov.f64 d0, 1.0;"
|
||||
"vadd.f64 %P[my_double], %P[my_double], d0;"
|
||||
: [my_double] "+w" (my_double)
|
||||
:
|
||||
: "d0"
|
||||
);
|
||||
assert(my_double == 2.5);
|
||||
}
|
||||
32
userland/arch/arm/c/inc_memory.c
Normal file
32
userland/arch/arm/c/inc_memory.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/* Like inc.c but less good since we do more work ourselves.
|
||||
*
|
||||
* Just doing this to test out the "m" memory constraint.
|
||||
*
|
||||
* GCC 8.2.0 -O0 assembles ldr line to:
|
||||
*
|
||||
* ....
|
||||
* ldr r0, [fp, #-12]
|
||||
* ....
|
||||
*
|
||||
* and `-O3` assembles to:
|
||||
*
|
||||
* ....
|
||||
* ldr r0, [sp]
|
||||
* ....
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
int main(void) {
|
||||
uint32_t my_local_var = 1;
|
||||
__asm__ (
|
||||
"ldr r0, %[my_local_var];"
|
||||
"add r0, r0, #1;"
|
||||
"str r0, %[my_local_var];"
|
||||
: [my_local_var] "+m" (my_local_var)
|
||||
:
|
||||
: "r0"
|
||||
);
|
||||
assert(my_local_var == 2);
|
||||
}
|
||||
25
userland/arch/arm/c/inc_memory_global.c
Normal file
25
userland/arch/arm/c/inc_memory_global.c
Normal file
@@ -0,0 +1,25 @@
|
||||
/* GCC 8.2.0 -O0 and -O3 assembles ldr line to:
|
||||
*
|
||||
* ....
|
||||
* movw r3, #<lower address part>
|
||||
* movt r3, #<higher address part>
|
||||
* ldr r0, [r3]
|
||||
* ....
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
uint32_t my_global_var = 1;
|
||||
|
||||
int main(void) {
|
||||
__asm__ (
|
||||
"ldr r0, %[my_global_var];"
|
||||
"add r0, r0, #1;"
|
||||
"str r0, %[my_global_var];"
|
||||
: [my_global_var] "+m" (my_global_var)
|
||||
:
|
||||
: "r0"
|
||||
);
|
||||
assert(my_global_var == 2);
|
||||
}
|
||||
38
userland/arch/arm/c/reg_var.c
Normal file
38
userland/arch/arm/c/reg_var.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/* https://github.com/cirosantilli/arm-assembly-cheat#register-variables */
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
int main(void) {
|
||||
register uint32_t r0 __asm__ ("r0");
|
||||
register uint32_t r1 __asm__ ("r1");
|
||||
uint32_t new_r0;
|
||||
uint32_t new_r1;
|
||||
{
|
||||
/* We must set the registers immediately before calling,
|
||||
* without making any function calls in between.
|
||||
*/
|
||||
r0 = 1;
|
||||
r1 = 2;
|
||||
__asm__ (
|
||||
/* We intentionally use an explicit r0 and r1 here,
|
||||
* just to illustrate that we are certain that the
|
||||
* r0 variable will go in r0. Real code would never do this.
|
||||
*/
|
||||
"add %[r0], r0, #1;"
|
||||
"add %[r1], r1, #1;"
|
||||
/* We have to specify r0 in the constraints.*/
|
||||
: [r0] "+r" (r0),
|
||||
[r1] "+r" (r1)
|
||||
:
|
||||
:
|
||||
);
|
||||
/* When we are done, we must immediatly assign
|
||||
* the register variables to regular variables.
|
||||
*/
|
||||
new_r0 = r0;
|
||||
new_r1 = r1;
|
||||
}
|
||||
assert(new_r0 == 2);
|
||||
assert(new_r1 == 3);
|
||||
}
|
||||
Reference in New Issue
Block a user