asm: more links

This commit is contained in:
Ciro Santilli 六四事件 法轮功
2019-05-05 00:00:00 +00:00
parent 549bd4a7fd
commit 3388d72bb2
25 changed files with 154 additions and 27 deletions

View File

@@ -11380,6 +11380,11 @@ TODO
Notice how we give the actual assembly line number where the failing assert was! Notice how we give the actual assembly line number where the failing assert was!
Other setup sanity checks that you might want to look into include:
* link:userland/arch/empty.S[]
* link:userland/arch/fail.S[]
=== User vs system assembly === User vs system assembly
By "userland assembly", we mean "the parts of the ISA which can be freely used from userland". By "userland assembly", we mean "the parts of the ISA which can be freely used from userland".
@@ -11388,12 +11393,82 @@ Most ISAs are divided into a system and userland part, and to running the system
One big difference between both is that we can run userland assembly on <<userland-setup>>, which is easier to get running and debug. One big difference between both is that we can run userland assembly on <<userland-setup>>, which is easier to get running and debug.
In particular, all the examples outside of <<linux-system-calls,freestanding directories>> link to the C standard library for IO, which is very convenient and portable across host OSes. In particular, most userland assembly examples link to the C standard library: <<userland-assembly-c-standard-library>>.
Userland assembly is generally simpler, and a pre-requisite for <<baremetal-setup>>. Userland assembly is generally simpler, and a pre-requisite for <<baremetal-setup>>.
System-land assembly cheats will be put under: <<baremetal-setup>>. System-land assembly cheats will be put under: <<baremetal-setup>>.
=== Userland assembly C standard library
All examples outside of <<linux-system-calls,freestanding directories>> link to the C standard library.
This allows using the C standard library for IO, which is very convenient and portable across host OSes.
It also exposes other non-IO functionality that is very convenient such as `memcmp`.
The C standard library infrastructure is implemented in the following files:
* link:userland/arch/main.c[]
* link:userland/arch/common.h[]
* link:userland/arch/x86_64/common_arch.h[]
* link:userland/arch/arm/common_arch.h[]
* link:userland/arch/aarch64/common_arch.h[]
=== Inline assembly
Examples under `arch/<arch>/c/` directories show to how use inline assembly from higher level languages such as C:
* x86_64
** link:userland/arch/x86_64/c/inc.c[]
** link:userland/arch/x86_64/c/add.c[]
* arm
** link:userland/arch/arm/c/inc.c[]
** link:userland/arch/arm/c/inc_memory.c[]
** link:userland/arch/arm/c/inc_memory_global.c[]
** link:userland/arch/arm/c/add.c[]
* aarch64
** link:userland/arch/aarch64/c/earlyclobber.c[]
** link:userland/arch/aarch64/c/inc.c[]
** link:userland/arch/aarch64/c/multiline.cpp[]
==== Inline assembly register variables
Used notably in some of the <<linux-system-calls>> setups:
* link:userland/arch/arm/reg_var.c[]
* link:userland/arch/aarch64/reg_var.c[]
* link:userland/arch/aarch64/reg_var_float.c[]
In x86, makes it possible to access variables not exposed with the one letter register constraints.
In arm, it is the only way to achieve this effect: https://stackoverflow.com/questions/10831792/how-to-use-specific-register-in-arm-inline-assembler
==== Inline assembly scratch registers
How to use temporary registers in inline assembly:
* x86_64
** link:userland/arch/x86_64/c/scratch.c[]
** link:userland/arch/x86_64/c/scratch_hardcode.c[]
Bibliography: https://stackoverflow.com/questions/6682733/gcc-prohibit-use-of-some-registers/54963829#54963829
==== Inline assembly early-clobbers
An example of using the `&` early-clobber modifier: link:userland/arch/aarch64/earlyclobber.c
More details at: https://stackoverflow.com/questions/15819794/when-to-use-earlyclobber-constraint-in-extended-gcc-inline-assembly/54853663#54853663
The assertion may fail without it. It actually does fail in GCC 8.2.0.
==== Inline assembly floating point ARM
Not documented as of GCC 8.2, but possible: https://stackoverflow.com/questions/53960240/armv8-floating-point-output-inline-assembly
* link:userland/arch/arm/c/inc_float.c[]
* link:userland/arch/aarch64/c/inc_float.c[]
=== Linux system calls === Linux system calls
The following <<userland-setup>> programs illustrate how to make system calls: The following <<userland-setup>> programs illustrate how to make system calls:
@@ -11436,11 +11511,35 @@ Determining the ARM syscall interface:
Questions about the C inline assembly examples: Questions about the C inline assembly examples:
* x86_64: https://stackoverflow.com/questions/9506353/how-to-invoke-a-system-call-via-sysenter-in-inline-assembly/54956854#54956854
* ARM: https://stackoverflow.com/questions/21729497/doing-a-syscall-without-libc-using-arm-inline-assembly
=== Calling conventions
* x86_64 * x86_64
** https://stackoverflow.com/questions/9506353/how-to-invoke-a-system-call-via-sysenter-in-inline-assembly/54956854#54956854 ** link:userland/arch/x86_64/common_arch.h[] `ENTRY` and `EXIT`
* ARM
** https://stackoverflow.com/questions/10831792/how-to-use-specific-register-in-arm-inline-assembler ==== ARM calling convention
** https://stackoverflow.com/questions/21729497/doing-a-syscall-without-libc-using-arm-inline-assembly
Call C standard library functions from assembly and vice versa.
* arm
** link:userland/arch/arm/common_arch.h[] `ENTRY` and `EXIT`
** link:userland/arch/arm/c_from_asm.S[]
* aarch64
** link:userland/arch/aarch64/common_arch.h[] `ENTRY` and `EXIT`
** link:userland/arch/aarch64/c/asm_from_c.c[]
ARM Architecture Procedure Call Standard (AAPCS) is the name that ARM Holdings gives to the calling convention.
Official specification: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf
Bibliography:
* https://en.wikipedia.org/wiki/Calling_convention#ARM_(A32) Wiki contains the master list as usual.
* http://stackoverflow.com/questions/8422287/calling-c-functions-from-arm-assembly
* http://stackoverflow.com/questions/261419/arm-to-c-calling-convention-registers-to-save
* https://stackoverflow.com/questions/10494848/arm-whats-the-difference-between-apcs-and-aapcs-abi
== x86 userland assembly == x86 userland assembly

View File

@@ -1,4 +1,4 @@
/* https://github.com/cirosantilli/arm-assembly-cheat#calling-convention */ /* https://github.com/cirosantilli/linux-kernel-module-cheat#arm-calling-convention */
#include <assert.h> #include <assert.h>
#include <inttypes.h> #include <inttypes.h>

View File

@@ -1,8 +1,4 @@
/* An example of using the '&' earlyclobber modifier. /* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly-early-clobbers */
* https://stackoverflow.com/questions/15819794/when-to-use-earlyclobber-constraint-in-extended-gcc-inline-assembly/54853663#54853663
* The assertion may fail without it. It actually does fail in GCC 8.2.0 at
* 34017bcd0bc96a3cf77f6acba4d58350e67c2694 + 1.
*/
#include <assert.h> #include <assert.h>
#include <inttypes.h> #include <inttypes.h>

View File

@@ -1,3 +1,8 @@
/* Increment a variable in inline assembly.
*
* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly
*/
#include <assert.h> #include <assert.h>
#include <inttypes.h> #include <inttypes.h>

View File

@@ -1,7 +1,4 @@
/* https://stackoverflow.com/questions/53960240/armv8-floating-point-output-inline-assembly /* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly-floating-point-arm */
*
* We use the undocumented %s and %d modifiers!
*/
#include <assert.h> #include <assert.h>

View File

@@ -1,4 +1,4 @@
/* https://github.com/cirosantilli/arm-assembly-cheat#register-variables */ /* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly-register-variables */
#include <assert.h> #include <assert.h>
#include <inttypes.h> #include <inttypes.h>

View File

@@ -1,4 +1,4 @@
/* https://github.com/cirosantilli/arm-assembly-cheat#register-variables */ /* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly-register-variables */
#include <assert.h> #include <assert.h>
#include <inttypes.h> #include <inttypes.h>

View File

@@ -1,3 +1,5 @@
/* https://github.com/cirosantilli/linux-kernel-module-cheat#userland-assembly-c-standard-library */
#ifndef COMMON_ARCH_H #ifndef COMMON_ARCH_H
#define COMMON_ARCH_H #define COMMON_ARCH_H

View File

@@ -1,4 +1,7 @@
/* 1 + 2 == 3 */ /* 1 + 2 == 3
*
* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly
*/
#include <assert.h> #include <assert.h>
#include <inttypes.h> #include <inttypes.h>

View File

@@ -1,4 +1,7 @@
/* Increment a variable in inline assembly. */ /* Increment a variable in inline assembly.
*
* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly
*/
#include <assert.h> #include <assert.h>
#include <inttypes.h> #include <inttypes.h>

View File

@@ -1,4 +1,4 @@
/* https://stackoverflow.com/questions/53960240/armv8-floating-point-output-inline-assembly */ /* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly-floating-point-arm */
#include <assert.h> #include <assert.h>

View File

@@ -13,6 +13,8 @@
* .... * ....
* ldr r0, [sp] * ldr r0, [sp]
* .... * ....
*
* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly
*/ */
#include <assert.h> #include <assert.h>

View File

@@ -5,6 +5,8 @@
* movt r3, #<higher address part> * movt r3, #<higher address part>
* ldr r0, [r3] * ldr r0, [r3]
* .... * ....
*
* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly
*/ */
#include <assert.h> #include <assert.h>

View File

@@ -1,4 +1,4 @@
/* https://github.com/cirosantilli/arm-assembly-cheat#register-variables */ /* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly-register-variables */
#include <assert.h> #include <assert.h>
#include <inttypes.h> #include <inttypes.h>

View File

@@ -17,7 +17,7 @@ ENTRY
/* r0 is first argument. */ /* r0 is first argument. */
ldr r0, =puts_s ldr r0, =puts_s
bl puts bl puts
/* Check exit statut >= 0 for success. */ /* Check exit status >= 0 for success. */
cmp r0, 0 cmp r0, 0
ASSERT(bge) ASSERT(bge)

View File

@@ -1,3 +1,5 @@
/* https://github.com/cirosantilli/linux-kernel-module-cheat#userland-assembly-c-standard-library */
#ifndef COMMON_ARCH_H #ifndef COMMON_ARCH_H
#define COMMON_ARCH_H #define COMMON_ARCH_H

View File

@@ -1,3 +1,5 @@
/* https://github.com/cirosantilli/linux-kernel-module-cheat#userland-assembly-c-standard-library */
#ifndef COMMON_H #ifndef COMMON_H
#define COMMON_H #define COMMON_H

View File

@@ -1,4 +1,6 @@
/* https://github.com/cirosantilli/arm-assembly-cheat#about */ /* Please don't do anything, including crashing.
* https://github.com/cirosantilli/linux-kernel-module-cheat#userland-assembly
*/
#include "common.h" #include "common.h"

View File

@@ -1,4 +1,6 @@
/* See what happens on test failure. */ /* See what happens on test failure.
* https://github.com/cirosantilli/linux-kernel-module-cheat#userland-assembly
*/
#include "common.h" #include "common.h"

View File

@@ -1,4 +1,6 @@
/* This is the main entrypoint for all .S examples. */ /* This is the main entry point for all .S examples.
* https://github.com/cirosantilli/linux-kernel-module-cheat#userland-assembly-c-standard-library
*/
#include "stdio.h" #include "stdio.h"
#include "stdint.h" #include "stdint.h"

View File

@@ -1,3 +1,5 @@
/* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly */
#include <assert.h> #include <assert.h>
#include <inttypes.h> #include <inttypes.h>

View File

@@ -1,3 +1,5 @@
/* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly */
#include <assert.h> #include <assert.h>
#include <inttypes.h> #include <inttypes.h>

View File

@@ -1,4 +1,4 @@
/* https://stackoverflow.com/questions/6682733/gcc-prohibit-use-of-some-registers/54963829#54963829 */ /* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly-scratch-registers */
#include <assert.h> #include <assert.h>
#include <inttypes.h> #include <inttypes.h>

View File

@@ -1,4 +1,6 @@
/* This is a worse version of scratch.c with hardcoded scratch. */ /* This is a worse version of scratch.c with hardcoded scratch.
* https://github.com/cirosantilli/linux-kernel-module-cheat#inline-assembly-scratch-registers
*/
#include <assert.h> #include <assert.h>
#include <inttypes.h> #include <inttypes.h>

View File

@@ -1,3 +1,5 @@
/* https://github.com/cirosantilli/linux-kernel-module-cheat#userland-assembly-c-standard-library */
#ifndef COMMON_ARCH_H #ifndef COMMON_ARCH_H
#define COMMON_ARCH_H #define COMMON_ARCH_H