# Linux Kernel Module Cheat

## 28. Userland assembly

Programs under `userland/arch/<arch>/` are examples of userland assembly programming.

This section will document ISA agnostic concepts, and you should read it first.

ISA specifics are covered at:

- x86 userland assembly under userland/arch/x86_64/, originally migrated from: https://github.com/cirosantilli/x86-assembly-cheat

- ARM userland assembly originally migrated from https://github.com/cirosantilli/arm-assembly-cheat under:

  - userland/arch/arm/

  - userland/arch/aarch64/

Like other userland programs, these programs can be run as explained at: Section 2.8, “Userland setup”.

As a quick reminder, the fastest setups to get started are:

- Userland setup getting started natively if your host can run the examples, e.g. x86 example on an x86 host:

- Userland setup getting started with prebuilt toolchain and QEMU user mode otherwise

However, as usual, it is saner to build your toolchain as explained at: Section 11.1, “QEMU user mode getting started”.

The first examples you should look into are:

- add

  - userland/arch/x86_64/add.S

  - userland/arch/arm/add.S

  - userland/arch/aarch64/add.S

- mov between register and memory

  - userland/arch/x86_64/mov.S

  - ARM MOV instruction

  - ARM load and store instructions

- addressing modes

  - x86 addressing modes

  - ARM addressing modes

- registers, see: Section 28.1, “Assembly registers”

- jumping:

  - x86 control transfer instructions

  - ARM branch instructions

- SIMD

  - x86 SIMD

  - ARM SIMD

The add examples in particular:

- introduce the basics of how a given assembly works: how many inputs / outputs, who is input and output, can it use memory or just registers, etc.

  It is then a big copy paste for most other data instructions.

- verify that the venerable ADD instruction and our assertions are working

Now try to modify modify the x86_64 add program to see the assertion fail:

    LKMC_ASSERT_EQ(%rax, $4)

because 1 + 2 tends to equal 3 instead of 4.

And then watch the assertion fail:

    ./build-userland
    ./run --userland userland/arch/x86_64/add.S

with error message:

    assert_eq_64 failed
    val1 0x3
    val2 0x4
    error: asm_main returned 1 at line 8

and notice how the error message gives both:

- the actual assembly source line number where the failing assert was

- the actual and expected values

Other infrastructure sanity checks that you might want to look into include:

- userland/arch/empty.S

- `LKMC_FAIL` tests

  - userland/arch/lkmc_assert_fail.S

- `LKMC_ASSERT_EQ` tests

  - userland/arch/x86_64/lkmc_assert_eq_fail.S

  - userland/arch/arm/lkmc_assert_eq_fail.S

  - userland/arch/aarch64/lkmc_assert_eq_fail.S

- `LKMC_ASSERT_MEMCMP` tests

  - userland/arch/x86_64/lkmc_assert_memcmp_fail.S

  - userland/arch/arm/lkmc_assert_memcmp_fail.S

  - userland/arch/aarch64/lkmc_assert_memcmp_fail.S

- Assembly registers

- Floating point assembly

- SIMD assembly

- User vs system assembly

- Userland assembly C standard library

- GCC inline assembly

- Linux system calls

- Linux calling conventions

- GNU GAS assembler

- NOP instructions