You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+42-20Lines changed: 42 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@ An introduction to assembly on Apple Silicon Macs.
4
4
5
5
## Introduction
6
6
7
-
In this repository, I will code along with the book [Programming with 64-Bit ARM Assembly Language](https://www.apress.com/de/book/9781484258804?utm_medium=affiliate&utm_source=commission_junction&utm_campaign=3_nsn6445_product_PID%zp&utm_content=de_05032018#otherversion=9781484258804), adjusting all sample code for Apple's ARM64 line of computers. While Apple's marketing material seems to avoid a name for the platform and talks only about the M1 processor, the developer documentation uses the term "Apple Silicon". I will use this term in the following.
7
+
In this repository, I will code along with the book [Programming with 64-Bit ARM Assembly Language](https://www.dpbolvw.net/click-100586055-13091548?url=https%3A%2F%2Flink.springer.com%2Fbook%2F10.1007%2F978-1-4842-5881-1), adjusting all sample code for Apple's ARM64 line of computers. While Apple's marketing material seems to avoid a name for the platform and talks only about the M1 processor, the developer documentation uses the term "Apple Silicon". I will use this term in the following.
8
8
9
9
The original sourcecode can be found [here](https://github.com/Apress/programming-with-64-bit-ARM-assembly-language).
10
10
@@ -21,7 +21,7 @@ While I pretty much assume that people who made it here meet most if not all req
21
21
22
22
## Acknowledgments
23
23
24
-
I would like to thank @claui, @jannau, @jrosengarden, @m-schmidt, @saagarjha, and @zhuowei! They helped me when I hit a wall, or asked questions that let me improve the content.
24
+
I would like to thank [@claui](https://github.com/claui), [@jannau](https://github.com/jannau), [@jrosengarden](https://github.com/jrosengarden), [@m-schmidt](https://github.com/m-schmidt), [@saagarjha](https://github.com/saagarjha), and [@zhuowei](https://github.com/zhuoweir)! They helped me when I hit a wall, or asked questions that let me improve the content.
25
25
26
26
## Changes To The Book
27
27
@@ -31,7 +31,7 @@ Linux and Darwin, which were both inspired by [AT&T Unix System V](http://www.un
31
31
32
32
This file is organized so that you can read the book, and read about the differences for Apple Silicon side by side. The headlines in this document follow those in the book.
33
33
34
-
## Chapter 1
34
+
## Chapter 1: Getting Started
35
35
36
36
### Computers and Numbers
37
37
@@ -89,7 +89,7 @@ We know the `-o` switch, let's examine the others:
89
89
*`-e _start`: Darwin expects an entrypoint `_main`. In order to keep the sample both as close as possible to the book, and to allow it's use within the C-Sample from _Chapter 3_, I opted to keep `_start` and tell the linker that this is the entry point we want to use
90
90
*`-arch arm64` for good measure, let's throw in the option to cross-compile this from an Intel Mac. You can leave this off when running on Apple Silicon.
91
91
92
-
## Chapter 2
92
+
## Chapter 2: Loading and Adding
93
93
94
94
The changes from [Chapter 1](https://github.com/below/HelloSilicon#chapter-1) (makefile, alignment, system calls) have to be applied.
95
95
@@ -105,7 +105,7 @@ ADD X2, X1, W0, SXTB
105
105
```
106
106
The GNU Assembler seems to ignore this and allows you to specifiy a 64-Bit source register.
107
107
108
-
## Chapter 3
108
+
## Chapter 3: Tooling Up
109
109
110
110
### Beginning GDB
111
111
@@ -162,7 +162,7 @@ That said, while it is possible to build an iOS executable with the command line
162
162
163
163
As [Chapter 10](https://github.com/below/HelloSilicon#chapter-10) focusses on building an app that will run on iOS, I have chosen to simply create a Command Line Tool here which is now using the same `HelloWorld.s` file.
164
164
165
-
## Chapter 4
165
+
## Chapter 4: Controlling Programm Flow
166
166
167
167
Besides the common changes, we face a new issue which is described in the book in Chapter 5: Darwin does not like `LSR X1, =symbol`, it will produce the error `ld: Absolute addressing not allowed in arm64 code`. If we use `ASR X1, symbol`, as suggested in Chapter 3 of the book, our data has to be in the read-only `.text` section. In this sample however, we want writable data.
168
168
@@ -193,7 +193,7 @@ I was asked how to read the command line, and I gladly [answered](https://github
193
193
194
194
Sample code can be found in Chapter 4 in the file [`case.s`](Chapter%2004/case.s).
195
195
196
-
## Chapter 5
196
+
## Chapter 5: Thanks for the Memories
197
197
198
198
The important differences in memory addressing for Darwin were already addresed above.
199
199
@@ -204,22 +204,22 @@ The `quad`, `octa` and `fill` keywords must be in lowercase for the llvm assembl
204
204
205
205
Changes like in Chapter 4.
206
206
207
-
## Chapter 6
207
+
## Chapter 6: Functions and the Stack
208
208
209
209
As we learned in Chapter 5, all assembler directives (like `.equ`) must be in lowercase.
210
210
211
-
## Chapter 7
211
+
## Chapter 7: Linux Operating System Services
212
212
`asm/unistd.h` does not exist in the Apple SDKs, instead `sys/syscalls.h` can be used.
213
213
214
214
It is also important to notice that while the calls and definitions look similar, Linux and Darwin are not the same: `AT_FDCWD` is -100 on Linux, but must be -2 on Darwin.
215
215
216
216
Unlike Linux, errors are signified by setting the carry flag, and the error codes are non-negative. We therefore `MOV` the result into the required register instead of `ADDS` (we don't need to check for negative numbers, and need to preserve the condition flags) and B.CC to the success path.
217
217
218
-
## Chapter 8
218
+
## Chapter 8: Programming GPIO Pins
219
219
220
220
This chapter is specifically for the Raspberry Pi 4, so there is nothing to do here.
221
221
222
-
## Chapter 9
222
+
## Chapter 9: Interacting with C and Python
223
223
224
224
For transparency reasons, I replaced `gcc` with `clang`.
225
225
@@ -266,27 +266,49 @@ While we are using the LLVM toolchain, in assembly — including inline-assembly
266
266
267
267
Also, the size of one variable had to be changed from int to long to make the compiler complete happy and remove all warnings
268
268
269
+
### Calling Assembly from Python
270
+
271
+
Note that as of this writing, all Python IDEs for macOS attempt to load x86\_64 libraries, even when the app itself is universal. So currently the only way to run the sample is on the command line. Also, as of macOS 12.3, Apple [removed Python 2](https://developer.apple.com/documentation/macos-release-notes/macos-12_3-release-notes), and developers should use Python 3.
272
+
269
273
### Listing 9-9
270
274
271
-
While the `uppertst5.py` file only needed a minimal change, calling the code is a little more challenging: On Apple Silicon Macs, python is a Mach-O universal binary with two architectures: x86_64 and arm64e. Notably absent is the arm64 architecture we were building for up to this point. This makes our dylib unusable with python.
275
+
While the `uppertst5.py` file only needed a minimal change, calling the code is a little more challenging. On Apple Silicon Macs, Python is a Mach-O universal binary with two architectures, x86\_64 and arm64e:
276
+
277
+
```
278
+
% lipo -info /usr/bin/python3
279
+
Architectures in the fat file: /usr/bin/python3 are: x86_64 arm64e
280
+
```
281
+
282
+
Notably absent is the arm64 architecture we were building for up to this point. This makes our dylib unusable with Python.
272
283
273
284
arm64e is the [Armv-8 architecture](https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/armv8-a-architecture-2016-additions), which Apple is using since the A12 chip. If you want to address devices prior to the A12, you must stick to arm64. The first Macs to use ARM64 run on the M1 CPU based on the A14 architecture, thus Apple decided to take advangage of the new features.
274
285
275
286
So, what to do? We could compile everything as arm64e, but that would make the library useless on devices like the iPhone X or older, and we would like to support them, too.
276
287
277
-
Above, you read something about a _universal binary_. For a very long time, the Mach-O executable format had support for several processor architectures in a single file. This includes, but is not limited to, Motorola 68k (on NeXT computers), PowerPC, Intel x86, as well ARM code, each with their 32 and 64 bit variantes where applicable. In this case, I am building a universal dynamic library which includes both arm64 and arm64e code. More information can be found [here](https://developer.apple.com/documentation/xcode/building_a_universal_macos_binary).
288
+
Above, you read something about a _universal binary_. For a very long time, the Mach-O executable format was supporting several processor architectures in a single file. This includes, but is not limited to, Motorola 68k (on NeXT computers), PowerPC, Intel x86, as well ARM code, each with their 32 and 64 bit variantes where applicable. In this case, I am building a universal dynamic library which includes both arm64 and arm64e code. More information can be found [here](https://developer.apple.com/documentation/xcode/building_a_universal_macos_binary).
289
+
290
+
As mentioned above, no currently available Python IDE on macOS will load the ARM64 library, so use the command line to run your code:
291
+
292
+
```
293
+
% python3 uppertst5.py
294
+
b'This is a test!'
295
+
b'THIS IS A TEST!'
296
+
16
297
+
```
298
+
299
+
## Chapter 10: Interfacing with Kotlin and Swift
278
300
279
-
## Chapter 10
280
301
No changes in the core code were required, but instead of just an iOS app I created a SwiftUI app that will work on macOS, iOS, watchOS (Series 4 and later), and tvOS.
281
302
282
-
## Chapter 11
303
+
## Chapter 11: Multiply, Divide, and Accumulate
304
+
283
305
At this point, the changes should be self-explainatory. The usual makefile adjustments, `.align 4`, address mode changes, and `_printf` adjustments.
284
306
285
-
## Chapter 12
307
+
## Chapter 12: Floating-Point Operations
286
308
287
309
Like in Chapter 11, all the chages have been introduced already. Nothing new here.
288
310
289
-
## Chapter 13
311
+
## Chapter 13: Neon Coprocessor
290
312
291
313
Once again, the Clang assembler wants a slightly different syntax: Where gcc accepts
292
314
@@ -302,11 +324,11 @@ MUL.4H V6, V0, V3[0]
302
324
303
325
All other changes to the code should be trivial at this point.
304
326
305
-
## Chapter 14
327
+
## Chapter 14: Optimizing Code
306
328
307
329
No unusal changes here.
308
330
309
-
## Chapter 15
331
+
## Chapter 15: Reading and Understanding Code
310
332
311
333
### Copying a Page of Memory
312
334
@@ -321,7 +343,7 @@ No changes were required. The "tiny" code model is not supported for Mach-O exce
321
343
fatal error: error in backend: tiny code model is only supported on ELF
322
344
```
323
345
324
-
## Chapter 16
346
+
## Chapter 16: Hacking Code
325
347
326
348
All that can be said is that clang automatically enables position-independent executables, and the option `-no-pie` does not work. Therefore, the exploit shown in the `upper.s` file can not be reproduced.
0 commit comments