mirror of
https://github.com/pkivolowitz/asm_book.git
synced 2026-06-23 07:28:04 +08:00
working on convergence macros
This commit is contained in:
parent
4ec5ca1e45
commit
ed62038965
3 changed files with 156 additions and 8 deletions
156
macros/README.md
156
macros/README.md
|
|
@ -1 +1,157 @@
|
||||||
|
# Apple / Linux Convergence Macros
|
||||||
|
|
||||||
|
This chapter documents the ongoing work in defining a macro suite that
|
||||||
|
allows coding AARCH64 programs once with the ability to build correctly
|
||||||
|
on Apple Silicon and Linux machines without change.
|
||||||
|
|
||||||
|
The work is ongoing and subject to change.
|
||||||
|
|
||||||
|
There are limits to what these macros can do. Variadic functions such as
|
||||||
|
`printf()` must be handled via parallel code paths (i.e. use of `#if`).
|
||||||
|
|
||||||
|
## Make assembly language file names end in .S
|
||||||
|
|
||||||
|
For widest compatibility, end your assembly language files in capital S
|
||||||
|
rather than small s. This forces `gcc` to make use of the C preprocessor
|
||||||
|
as there is no command line option to make it do so. `clang` (and a
|
||||||
|
`gcc` derived from it) may or may not have a command line option to
|
||||||
|
force the invocation of the preprocessor but ending your file names
|
||||||
|
in capital S is universally appropriate.
|
||||||
|
|
||||||
|
## Prepended underscores
|
||||||
|
|
||||||
|
A main difference unified by the macros is Apple's prepending of
|
||||||
|
underscores to labels defined by libraries such as the CRT and certain
|
||||||
|
other symbols like `main`.
|
||||||
|
|
||||||
|
So, `main` will not be found by the linker on Apple systems and `_main`
|
||||||
|
will be an error on Linux systems. There are macros to adjust for this.
|
||||||
|
|
||||||
|
There are some exceptions such as making use of `FILE * stdin`. On
|
||||||
|
Linux this would be `stdin`. On Mac OS you would expect `_stdin` but
|
||||||
|
you'd be wrong... instead Apple uses `___stdinp`. Why? Apple.
|
||||||
|
|
||||||
|
## Macros of general use
|
||||||
|
|
||||||
|
These macros don't converge Apple and Linux. They're just nice to have.
|
||||||
|
|
||||||
|
### PUSH_P, PUSH_R, POP_P and POP_R
|
||||||
|
|
||||||
|
These macros save some repetitive typing. For example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
PUSH_P x29, x30
|
||||||
|
```
|
||||||
|
|
||||||
|
resolves to:
|
||||||
|
|
||||||
|
```text
|
||||||
|
stp x29, x30, [sp, -16]!
|
||||||
|
```
|
||||||
|
|
||||||
|
### START_PROC and END_PROC
|
||||||
|
|
||||||
|
Place START_PROC after the label introducing a function.
|
||||||
|
|
||||||
|
Place END_PROC after the last `ret` of the function.
|
||||||
|
|
||||||
|
These resolve to: `.cfi_startproc` and `.cfi_endproc` respectively.
|
||||||
|
|
||||||
|
### MIN and MAX
|
||||||
|
|
||||||
|
Handy more readable macros for determining minima and maxima.
|
||||||
|
|
||||||
|
`MIN x0, x1, x2`
|
||||||
|
|
||||||
|
resolves to:
|
||||||
|
|
||||||
|
`csel x2, x0, x1, GT` putting the minimum of `x0` and `x1` into `x2`.
|
||||||
|
|
||||||
|
## Loads and Stores
|
||||||
|
|
||||||
|
### GLD_PTR
|
||||||
|
|
||||||
|
Loads the address of a label and then dereferences it where, on Apple
|
||||||
|
the label is in the global space and on Linux is a relatively close
|
||||||
|
label.
|
||||||
|
|
||||||
|
Apple version:
|
||||||
|
|
||||||
|
```text
|
||||||
|
.macro GLD_PTR xreg, label // Dereference a global *
|
||||||
|
adrp \xreg, _\label@GOTPAGE
|
||||||
|
ldr \xreg, [\xreg, _\label@GOTPAGEOFF]
|
||||||
|
.endm
|
||||||
|
```
|
||||||
|
|
||||||
|
Linux version:
|
||||||
|
|
||||||
|
```text
|
||||||
|
.macro GLD_PTR xreg, label // Dereference a global *
|
||||||
|
ldr \xreg, =\label
|
||||||
|
ldr \xreg, [\xreg]
|
||||||
|
.endm
|
||||||
|
```
|
||||||
|
|
||||||
|
### LLD_ADDR
|
||||||
|
|
||||||
|
Load the value of a "local" label.
|
||||||
|
|
||||||
|
Apple version:
|
||||||
|
|
||||||
|
```text
|
||||||
|
.macro LLD_ADDR xreg, label // Load a local address
|
||||||
|
adrp \xreg, \label@PAGE
|
||||||
|
add \xreg, \xreg, \label@PAGEOFF
|
||||||
|
.endm
|
||||||
|
```
|
||||||
|
|
||||||
|
Linux version:
|
||||||
|
|
||||||
|
```text
|
||||||
|
.macro LLD_ADDR xreg, label
|
||||||
|
ldr \xreg, =\label
|
||||||
|
.endm
|
||||||
|
```
|
||||||
|
|
||||||
|
## Extern a global label
|
||||||
|
|
||||||
|
Makes a label available externally.
|
||||||
|
|
||||||
|
Apple version:
|
||||||
|
|
||||||
|
```text
|
||||||
|
.macro GLABEL label
|
||||||
|
.global _\label
|
||||||
|
.endm
|
||||||
|
```
|
||||||
|
|
||||||
|
Linux version:
|
||||||
|
|
||||||
|
```text
|
||||||
|
.macro GLABEL label
|
||||||
|
.global \label
|
||||||
|
.endm
|
||||||
|
```
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
GLABEL main
|
||||||
|
```
|
||||||
|
|
||||||
|
## Calling functions
|
||||||
|
|
||||||
|
If you create your own function without an underscore, just call it as
|
||||||
|
usual.
|
||||||
|
|
||||||
|
If you need to call a function such as those found in the C runtime
|
||||||
|
library, use in this way:
|
||||||
|
|
||||||
|
```text
|
||||||
|
CRT strlen
|
||||||
|
```
|
||||||
|
|
||||||
|
## Declaring `main()`
|
||||||
|
|
||||||
|
Put `MAIN` on a line by itself. Notice there is no colon.
|
||||||
|
|
|
||||||
|
|
@ -71,10 +71,6 @@ main:
|
||||||
ldr \xreg, =\label
|
ldr \xreg, =\label
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
|
||||||
.macro LD_ADDR xreg, label
|
|
||||||
.endm
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.macro START_PROC // after starting label
|
.macro START_PROC // after starting label
|
||||||
|
|
|
||||||
|
|
@ -71,10 +71,6 @@ main:
|
||||||
ldr \xreg, =\label
|
ldr \xreg, =\label
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
|
||||||
.macro LD_ADDR xreg, label
|
|
||||||
.endm
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.macro START_PROC // after starting label
|
.macro START_PROC // after starting label
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue