mirror of
https://github.com/pkivolowitz/asm_book.git
synced 2026-06-21 02:06:48 +08:00
made hello world build on Apple
This commit is contained in:
parent
3054b7be1e
commit
f301a4024a
4 changed files with 207 additions and 9 deletions
6
section_1/hello_world/.vscode/settings.json
vendored
Normal file
6
section_1/hello_world/.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"cSpell.ignoreWords": [
|
||||
"onditionally",
|
||||
"onsole"
|
||||
]
|
||||
}
|
||||
|
|
@ -10,6 +10,11 @@ the C into ARM V8 assembly language.
|
|||
At every step, we'll completely explain the code and document what has
|
||||
changed from version to version so that little background is assumed.
|
||||
|
||||
[Special Bonus](#special-bonus---build-on-linux-and-apple-silicon) can
|
||||
be found by following the link. The code found there uses the macro
|
||||
suite developed by the author that allows code to be written once and
|
||||
built on both the Mac M family as well as on Linux.
|
||||
|
||||
## V1 in C++
|
||||
|
||||
Here is the code to a program that prints to the console, the contents
|
||||
|
|
@ -670,18 +675,62 @@ job.
|
|||
We do maintain that understanding assembly language principles will
|
||||
improve your higher level language coding.
|
||||
|
||||
## Special Bonus - Build on Linux AND Apple Silicon
|
||||
|
||||
[Here](./v6.S) is the source code shown below.
|
||||
|
||||
[Here](./apple-linux-convergence.S) is the source code to the macro
|
||||
suite that allows you to write the code once and build on both the Apple
|
||||
M family and upon Linux.
|
||||
|
||||
The documentation can be found [here](./../../macros/).
|
||||
|
||||
```text
|
||||
#include "apple-linux-convergence.S" // 1
|
||||
// 2
|
||||
.text // 3
|
||||
.p2align 2 // 4
|
||||
GLABEL main // 5
|
||||
// 6
|
||||
MAIN // 7
|
||||
PUSH_P x21, x30 // 8
|
||||
PUSH_R x29 // 9
|
||||
mov x29, sp // 10
|
||||
// 11
|
||||
mov x21, x1 // 12
|
||||
// 13
|
||||
1: ldr x0, [x21], 8 // 14
|
||||
cbz x0, 2f // 15
|
||||
CRT puts // 16
|
||||
b 1b // 17
|
||||
// 18
|
||||
2: POP_R x29 // 19
|
||||
POP_P x21, x30 // 20
|
||||
mov x0, xzr // 21
|
||||
ret // 22
|
||||
// 23
|
||||
.end // 24
|
||||
```
|
||||
|
||||
The push and pop macros simply save typing but the other macros sense
|
||||
if you are building on Linux or on Apple M family. In this case, the
|
||||
macros are helping with underscores but the macro suite contains more
|
||||
sophisticated helpers as well.
|
||||
|
||||
## Questions
|
||||
|
||||
### 1
|
||||
|
||||
(T | F) It is the compiler's job to reduce a higher level language to assembly language.
|
||||
(T | F) It is the compiler's job to reduce a higher level language to
|
||||
assembly language.
|
||||
|
||||
Answer: True - The "compiler" is just one step in the "compilation" process. In fact it
|
||||
is step 2. Invoking the "preprocessor" is step 1.
|
||||
Answer: True - The "compiler" is just one step in the "compilation"
|
||||
process. In fact it is step 2. Invoking the "preprocessor" is step 1.
|
||||
|
||||
### 2
|
||||
|
||||
(T | F) Failing to mark `main` as a `global` will result in a syntax error.
|
||||
(T | F) Failing to mark `main` as a `global` will result in a syntax
|
||||
error.
|
||||
|
||||
Answer: False - a linker error will happen, not a syntax error.
|
||||
|
||||
|
|
@ -689,8 +738,9 @@ Answer: False - a linker error will happen, not a syntax error.
|
|||
|
||||
\___ and ___ implement the braces in C and C++.
|
||||
|
||||
Answer: labels and branches - the closing brace of a `while` loop for example,
|
||||
is a branch instruction. The opening brace of a `while` is a label.
|
||||
Answer: labels and branches - the closing brace of a `while` loop for
|
||||
example, is a branch instruction. The opening brace of a `while` is a
|
||||
label.
|
||||
|
||||
### 4
|
||||
|
||||
|
|
@ -701,12 +751,14 @@ if a_register has value 0
|
|||
then goto label
|
||||
```
|
||||
|
||||
Answer: True - `cbz` stands for "compare and branch if zero". There is also
|
||||
a `cbnz` instruction. To test for other Boolean conditions, use `cmp`.
|
||||
Answer: True - `cbz` stands for "compare and branch if zero". There is
|
||||
also a `cbnz` instruction. To test for other Boolean conditions, use
|
||||
`cmp`.
|
||||
|
||||
### 5
|
||||
|
||||
While this chapter is entitled "Hello World," the example used isn't actually "Hello World." Here is a "Hello World" for you to complete:
|
||||
While this chapter is entitled "Hello World," the example used isn't
|
||||
actually "Hello World." Here is a "Hello World" for you to complete:
|
||||
|
||||
```text
|
||||
.global main
|
||||
|
|
|
|||
116
section_1/hello_world/apple-linux-convergence.S
Normal file
116
section_1/hello_world/apple-linux-convergence.S
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/* Macros to permit the "same" assembly language to build on ARM64
|
||||
Linux systems as well as Apple Silicon systems.
|
||||
|
||||
See the fuller documentation at:
|
||||
https://github.com/pkivolowitz/asm_book/blob/main/macros/README.md
|
||||
|
||||
Perry Kivolowitz
|
||||
A Gentle Introduction to Assembly Language
|
||||
*/
|
||||
|
||||
.macro GLD_PTR xreg, label
|
||||
#if defined(__APPLE__)
|
||||
adrp \xreg, _\label@GOTPAGE
|
||||
ldr \xreg, [\xreg, _\label@GOTPAGEOFF]
|
||||
#else
|
||||
ldr \xreg, =\label
|
||||
ldr \xreg, [\xreg]
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro GLD_ADDR xreg, label // Get a global address
|
||||
#if defined(__APPLE__)
|
||||
adrp \xreg, _\label@GOTPAGE
|
||||
add \xreg, \xreg, _\label@GOTPAGEOFF
|
||||
#else
|
||||
ldr \xreg, =\label
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro LLD_ADDR xreg, label
|
||||
#if defined(__APPLE__)
|
||||
adrp \xreg, \label@PAGE
|
||||
add \xreg, \xreg, \label@PAGEOFF
|
||||
#else
|
||||
ldr \xreg, =\label
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro LLD_DBL xreg, dreg, label
|
||||
#if defined(__APPLE__)
|
||||
adrp \xreg, \label@PAGE
|
||||
add \xreg, \xreg, \label@PAGEOFF
|
||||
ldur \dreg, [\xreg]
|
||||
// fmov \dreg, \xreg
|
||||
#else
|
||||
ldr \xreg, =\label
|
||||
ldur \dreg, [\xreg]
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro LLD_FLT xreg, sreg, label
|
||||
#if defined(__APPLE__)
|
||||
adrp \xreg, \label@PAGE
|
||||
add \xreg, \xreg, \label@PAGEOFF
|
||||
ldur \sreg, [\xreg]
|
||||
#else
|
||||
ldr \xreg, =\label
|
||||
ldur \sreg, [\xreg]
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro GLABEL label
|
||||
#if defined(__APPLE__)
|
||||
.global _\label
|
||||
#else
|
||||
.global \label
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro MAIN
|
||||
#if defined(__APPLE__)
|
||||
_main:
|
||||
#else
|
||||
main:
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro CRT label
|
||||
#if defined(__APPLE__)
|
||||
bl _\label
|
||||
#else
|
||||
bl \label
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro START_PROC // after starting label
|
||||
.cfi_startproc
|
||||
.endm
|
||||
|
||||
.macro END_PROC // after the return
|
||||
.cfi_endproc
|
||||
.endm
|
||||
|
||||
.macro PUSH_P a, b
|
||||
stp \a, \b, [sp, -16]!
|
||||
.endm
|
||||
|
||||
.macro PUSH_R a
|
||||
str \a, [sp, -16]!
|
||||
.endm
|
||||
|
||||
.macro POP_P a, b
|
||||
ldp \a, \b, [sp], 16
|
||||
.endm
|
||||
|
||||
.macro POP_R a
|
||||
ldr \a, [sp], 16
|
||||
.endm
|
||||
|
||||
.macro MIN src_a, src_b, dest
|
||||
csel \dest, \src_a, \src_b, GT
|
||||
.endm
|
||||
|
||||
.macro MAX src_a, src_b, dest
|
||||
csel \dest, \src_a, \src_b, LT
|
||||
.endm
|
||||
24
section_1/hello_world/v6.S
Normal file
24
section_1/hello_world/v6.S
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include "apple-linux-convergence.S"
|
||||
|
||||
.text
|
||||
.p2align 2
|
||||
GLABEL main
|
||||
|
||||
MAIN
|
||||
PUSH_P x21, x30
|
||||
PUSH_R x29
|
||||
mov x29, sp
|
||||
|
||||
mov x21, x1
|
||||
|
||||
1: ldr x0, [x21], 8
|
||||
cbz x0, 2f
|
||||
CRT puts
|
||||
b 1b
|
||||
|
||||
2: POP_R x29
|
||||
POP_P x21, x30
|
||||
mov x0, xzr
|
||||
ret
|
||||
|
||||
.end
|
||||
Loading…
Reference in a new issue