diff --git a/section_1/hello_world/.vscode/settings.json b/section_1/hello_world/.vscode/settings.json new file mode 100644 index 0000000..541088b --- /dev/null +++ b/section_1/hello_world/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "cSpell.ignoreWords": [ + "onditionally", + "onsole" + ] +} \ No newline at end of file diff --git a/section_1/hello_world/README.md b/section_1/hello_world/README.md index 7ec37f7..bbb8600 100644 --- a/section_1/hello_world/README.md +++ b/section_1/hello_world/README.md @@ -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 diff --git a/section_1/hello_world/apple-linux-convergence.S b/section_1/hello_world/apple-linux-convergence.S new file mode 100644 index 0000000..aae5135 --- /dev/null +++ b/section_1/hello_world/apple-linux-convergence.S @@ -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 diff --git a/section_1/hello_world/v6.S b/section_1/hello_world/v6.S new file mode 100644 index 0000000..33cad8e --- /dev/null +++ b/section_1/hello_world/v6.S @@ -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