below / hellosilicon Goto Github PK
View Code? Open in Web Editor NEWAn introduction to ARM64 assembly on Apple Silicon Macs
License: MIT License
An introduction to ARM64 assembly on Apple Silicon Macs
License: MIT License
Embedded platforms don't do static. However, if you're still curious here's how you can convince Xcode to make those files:
diff --git a/AsMain/main.s b/AsMain/main.s
index 953236a..61760cd 100644
--- a/AsMain/main.s
+++ b/AsMain/main.s
@@ -6,12 +6,11 @@
// X16 - Mach function number
//
-.global _main // Provide program starting address to linker
+.global start // Provide program starting address to linker
.align 2
-
// Setup the parameters to print hello world
// and then call Linux to do it.
-_main: mov X0, #1 // 1 = StdOut
+start: mov X0, #1 // 1 = StdOut
adr X1, helloworld // string to print
mov X2, #13 // length of our string
mov X16, #4 // linux write system call
diff --git a/MacAs.xcodeproj/project.pbxproj b/MacAs.xcodeproj/project.pbxproj
index 11b501e..f95d6bd 100644
--- a/MacAs.xcodeproj/project.pbxproj
+++ b/MacAs.xcodeproj/project.pbxproj
@@ -318,6 +318,8 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
+ LINK_WITH_STANDARD_LIBRARIES = NO;
+ OTHER_LDFLAGS = "-static";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
@@ -326,6 +328,8 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
+ LINK_WITH_STANDARD_LIBRARIES = NO;
+ OTHER_LDFLAGS = "-static";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
If you put an underscore in front of main
in both places and give up on static linking:
If you look at the book page 100-101, you will find that 0x1234FEDC4F5D6E3A is the correct answer. Please remove the incorrect fix. Removing the initialization of the output string makes the program completely useless.
I'm hoping you can possibly answer this question???
I've been working thru the book and your code changes in order for everything to work on the Machine We Must Not Speak About.
I'm trying to extend one of the Chapter 4 exercises and access the command line argument(s) (argc & argv) within my assembly code. I've searched high and low and just can't find anything that applies (or works).
Could you possibly provide any clues/hints on how to access the command line arguments (argv and argc) within the assembly program.
This very simple program is working fine but if you read the TODO, in the attached code, what I'm trying to do should make sense.
Thanks much!
As the title says. The original code has this too; the kernel doesn't care about null termination.
Hi,
Is it possible to build your examples into 32-bit binary and run on Apple Silicon Mac? If yes, what's the build command? Thanks!
To be clear, I haven't used the setup in HelloSilicon, I'm just using Xcode out of the box. Still, this might be relevant here as well.
One caveat I've come across is that GAS generates local symbols for labels starting with the letter l
. Thus, labels such as 'loop' are completely ignored by the debugger and breakpoint and single stepping behavior becomes weird. For example, setting a breakpoint anywhere in the loop will pause execution only at the next label in program order (say, cont
in upper.s). Also, single stepping and hitting a branch back to loop
(e.g. B.NE loop
) doesn't get back there, but again hits the next label. Just mentioning this, since many examples in the book have loop
s.
I really appreciate this repository, and this isn't an issue with it as such, but I wanted to ask if anyone here can provide an actual documentation page for the assembler apple uses. It seems the mac OS X Assembler guide (old copy at http://personal.denison.edu/~bressoud/cs281-s07/Assembler.pdf )is out of date, and there isn't a meaningful guide for clang llvm assmbler (I guess, that's because it's a framework, not an assembler with macros and directives).
I sortof managed to muddle through some of the problems, but there are differences between apple's old documentation and the gas manual. E.g. macros - they can take named parameters. But you can't redefine symbols with .set (which is sometimes quite useful). I'd be great to have an authoritative manual, or alternatives to the apple assembler. E.g., is there a yasm etc that can be used ? I asked around in other places, but not much success yet.
I'm hesitant to make this an issue here, as this isn't y'all's fault. However, it seems y'all had to figure some of this out and it would be great to share any expertise you might have. If this is an unreasonable imposition, please feel free to close this without a comment.
Many thanks in advance.
HelloSilicon/Chapter 01/HelloWorld.s
Line 15 in 3228b59
adr X1, helloworld
needs to be changed to:adrp x1, helloworld@PAGE
add x1, x1, helloworld@PAGEOFF
I tried to adapt the openat call to Darwin, but it returns 9, regardless of the input file (i.e. even when I would be expecting an error).
I have disassembled libsystem_kernel.dylib, and didn't really get wiser:
15548: b7 13 40 b9 ldr w23, [x29, #16]
1554c: e3 3e 00 12 and w3, w23, #0xffff
15550: e0 03 15 aa mov x0, x21
15554: e1 03 14 aa mov x1, x20
15558: e2 03 13 aa mov x2, x19
1555c: 27 b7 ff 97 bl ___openat
___openat:
31f8: f0 39 80 d2 mov x16, #463
31fc: 01 10 00 d4 svc #0x80
3200: e3 00 00 54 b.lo 0x321c
I can't really see a big difference in my call:
HelloSilicon/Chapter 7/fileio.S
Line 21 in a40f36e
If anyone has an idea …
I cloned the repo, did cd HelloSilicon/Chapter\ 02
, ran make
then ran these commands:
objdump -d movexamps
objdump -d -M no-aliases movexamps
objdump -d --macho movexamps
objdump -d --macho -M no-aliases movexamps
These 3
objdump -d movexamps
objdump -d --macho movexamps
objdump -d --macho -M no-aliases movexamps
produce the same disassembly:
$ objdump -d movexamps
movexamps: file format mach-o arm64
Disassembly of section __TEXT,__text:
0000000100003f7c <_start>:
100003f7c: 42 c7 8d d2 mov x2, #28218
100003f80: a2 eb a9 f2 movk x2, #20317, lsl #16
100003f84: 82 db df f2 movk x2, #65244, lsl #32
100003f88: 82 46 e2 f2 movk x2, #4660, lsl #48
100003f8c: e1 03 02 2a mov w1, w2
100003f90: 41 f8 7f d3 lsl x1, x2, #1
100003f94: 41 fc 41 d3 lsr x1, x2, #1
100003f98: 41 fc 41 93 asr x1, x2, #1
100003f9c: 41 04 c2 93 ror x1, x2, #1
100003fa0: 01 60 b5 d2 mov x1, #2868903936
100003fa4: a1 05 80 12 mov w1, #-46
100003fa8: 21 00 80 12 mov w1, #-2
100003fac: 00 00 80 d2 mov x0, #0
100003fb0: 30 00 80 d2 mov x16, #1
100003fb4: 01 10 00 d4 svc #0x80
$ objdump -d --macho movexamps
movexamps:
(__TEXT,__text) section
_start:
100003f7c: 42 c7 8d d2 mov x2, #28218
100003f80: a2 eb a9 f2 movk x2, #20317, lsl #16
100003f84: 82 db df f2 movk x2, #65244, lsl #32
100003f88: 82 46 e2 f2 movk x2, #4660, lsl #48
100003f8c: e1 03 02 2a mov w1, w2
100003f90: 41 f8 7f d3 lsl x1, x2, #1
100003f94: 41 fc 41 d3 lsr x1, x2, #1
100003f98: 41 fc 41 93 asr x1, x2, #1
100003f9c: 41 04 c2 93 ror x1, x2, #1
100003fa0: 01 60 b5 d2 mov x1, #2868903936
100003fa4: a1 05 80 12 mov w1, #-46
100003fa8: 21 00 80 12 mov w1, #-2
100003fac: 00 00 80 d2 mov x0, #0
100003fb0: 30 00 80 d2 mov x16, #1
100003fb4: 01 10 00 d4 svc #0x80
$ objdump -d --macho -M no-aliases movexamps
movexamps:
(__TEXT,__text) section
_start:
100003f7c: 42 c7 8d d2 mov x2, #28218
100003f80: a2 eb a9 f2 movk x2, #20317, lsl #16
100003f84: 82 db df f2 movk x2, #65244, lsl #32
100003f88: 82 46 e2 f2 movk x2, #4660, lsl #48
100003f8c: e1 03 02 2a mov w1, w2
100003f90: 41 f8 7f d3 lsl x1, x2, #1
100003f94: 41 fc 41 d3 lsr x1, x2, #1
100003f98: 41 fc 41 93 asr x1, x2, #1
100003f9c: 41 04 c2 93 ror x1, x2, #1
100003fa0: 01 60 b5 d2 mov x1, #2868903936
100003fa4: a1 05 80 12 mov w1, #-46
100003fa8: 21 00 80 12 mov w1, #-2
100003fac: 00 00 80 d2 mov x0, #0
100003fb0: 30 00 80 d2 mov x16, #1
100003fb4: 01 10 00 d4 svc #0x80
$
Only -M no-aliases
without --macho
changes any instructions
$ objdump -d -M no-aliases movexamps
movexamps: file format mach-o arm64
Disassembly of section __TEXT,__text:
0000000100003f7c <_start>:
100003f7c: 42 c7 8d d2 mov x2, #28218
100003f80: a2 eb a9 f2 movk x2, #20317, lsl #16
100003f84: 82 db df f2 movk x2, #65244, lsl #32
100003f88: 82 46 e2 f2 movk x2, #4660, lsl #48
100003f8c: e1 03 02 2a orr w1, wzr, w2
100003f90: 41 f8 7f d3 lsl x1, x2, #1
100003f94: 41 fc 41 d3 lsr x1, x2, #1
100003f98: 41 fc 41 93 asr x1, x2, #1
100003f9c: 41 04 c2 93 extr x1, x2, x2, #1
100003fa0: 01 60 b5 d2 mov x1, #2868903936
100003fa4: a1 05 80 12 mov w1, #-46
100003fa8: 21 00 80 12 mov w1, #-2
100003fac: 00 00 80 d2 mov x0, #0
100003fb0: 30 00 80 d2 mov x16, #1
100003fb4: 01 10 00 d4 svc #0x80
Although it only changes mov w1, w2
-> orr w1, wzr, w2
and ror x1, x2, #1
-> extr x1, x2, x2, #1
. I was promised that
HelloSilicon/Chapter 02/movexamps.s
Lines 37 to 41 in 9fc970d
but it stays the same
100003fa4: a1 05 80 12 mov w1, #-46
100003fa8: 21 00 80 12 mov w1, #-2
I'm on an M1 Macbook Air, macOS 13.2.1, Xcode version 14.1 (14B47b)
$ as --version
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: arm64-apple-darwin22.3.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ objdump --version
Apple LLVM version 14.0.0 (clang-1400.0.29.202)
Optimized build.
Default target: arm64-apple-darwin22.3.0
Host CPU: apple-a12
[...]
$ softwareupdate --list
Software Update Tool
Finding available software
No new software available.
Well...I'm back.....this time with a problem (self-inflicted wound?)
I've been moving merrily along through your "Hello Silicon" project...learning tons (and having a blast).
Along the way I've been keeping my "MWMNSA" up-to-date with the OS betas and the Xcode betas.
My problem started this morning when I (foolishly?) installed the publicly available version of Big Sur - 11.0.1
Now all my projects fail to compile/link successfully (actually the failure is during the link phase).
Here is a sample of the error I'm getting
jeffrosengarden@MacMiniDTK Chapter 4 % make case
ld -o case -lSystem -syslibroot xcrun -sdk macosx --show-sdk-path -e _start -arch arm64 case.o
ld: warning: ignoring file /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/lib/libSystem.tbd, missing required architecture arm64 in file /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/lib/libSystem.tbd
ld: dynamic main executables must link with libSystem.dylib for architecture arm64
make: *** [case] Error 1
I'm not sure what to do here. Any help/advice would be greatly appreciated.
Thanks much!
I've just started reading the book and when I got to the HelloWorld I noticed that the approach for doing system calls is different.
Since the repo went to trouble of stating where the terminal is (😅), I think a brief explanation of the differences would be important.
On the book (Linux):
...
_start: mov X0, #1 // 1 = StdOut
ldr X1, =helloworld // string to print
mov X2, #13 // length of our string
mov X8, #64 // Linux write system call
svc 0 // Call Linux to output the string
...
On the HelloSillicon repo (Mac):
...
_start: mov X0, #1 // 1 = StdOut
adr X1, helloworld // string to print
mov X2, #13 // length of our string
mov X16, #4 // Unix write system call
svc #0x80 // Call kernel to output the string
...
For starters, why the system call is different: The function number is different (64 and 4) due to each system having different conventions. The table for the Darwin (Apple) system calls can be found at the following link:Darwin System Calls.
This is however one specific version (the most recent at time of writing). Newer versions can be found at here.
Also due to system conventions, the address for storing the function numbers is different.
While on Linux is on X8, in Apple Sillicon is X16.
And for calling the interruption as well, while on Linux is 0, on Apple Sillicon is 0x80.
HelloSilicon/Chapter 13/matrixmultneon.s
Line 34 in 5cd41ac
While the distance code works, the matrixmultneon code does not, and building it leads to the following error:
<instantiation>:1:24: error: invalid operand for instruction
MUL V6.4H, V0.4H, V3.4H[0]
^
The book says:
MUL V6.4H, V0.4H, V3.4H[0]
This is multiplying each lane in V0 by the scalar contained in a specific lane of V3. This shows how we typically access a value in a specific lane by appending [lane number] to the end of the register specifier—counting lanes from zero.
Adding -arch arm64e
does not change anything.
Maybe @steipete has an idea?
"The stand-alone system assemblers for i386, x86_64, and arm are deprecated and may be removed in a future Xcode release. Using the as command with the -Q flag shows a warning that instructs you to transition to Clang’s integrated assembler and the -q flag. The as(1) driver will remain, as a standard way to invoke Clang’s integrated assembler, as well as any assemblers installed by the developer. (61299833)"
Hi, I'm really new to this row level world 🙏 and have an issue.
I'm not able to use the command with options, objdump -s -d -M no-aliases filename.o
, and it says "Unrecognized disassembler option: no-aliases"
I don't know why, can't I use that option on m1?
thank you, in advance.
Lines 21–23 are not required or were added by mistake, causing the program to output an incorrect string.
If we remove these three lines, the program works as expected.
Expected:
0x123456789ABCDEFG
Actual:
0x1234FEDC4F5D6E3A
I am very new to assembly; please let me know if I'm wrong somewhere.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.