苹果M1汇编语言Hello World

2021-01-15 20:26:16

上周,我们讨论了使用新的基于Apple M1的Macintosh作为开发工作站,以及如何安装Apple的开发系统XCode还安装了包括LLVM和make在内的大量开源开发工具。本周,我们将介绍如何编译和运行一个简单的命令行ARM汇编语言Hello World程序。

我的《用64位ARM汇编语言进行编程》一书包含了许多自包含的汇编语言程序示例,以及许多iOS和Android示例。使用GNU工具集为Linux编译了命令行实用程序。 Alex vonBelow接受了所有这些内容,并对其进行了修改,以与LLVM工具链配合使用并在Apple的开发环境中使用。他还处理了Linux与MacOS / iOS之间的所有差异。他的本书的源代码版本已针对苹果M1进行了修改,可在此处找到:

MacOS和Linux均基于Unix,并且相似之处多于不同。但是,需要注意一些差异:

MacOS默认使用LLVM,而Linux使用GNU GCC。就本文而言,这实际上仅影响makefile中的命令行参数。您可以在Linux上使用LLVM,并且GCC不久将可用于Apple M1。

MacOS链接器/加载器不喜欢重定位,因此您需要使用ADR而不是LDR指令来加载地址。您可以在Linux中使用ADR,如果执行此操作,则两者均可使用。

Unix API调用几乎相同,不同之处在于Linux在使用64位时重命名了功能号,而MacOS则使功能号保持不变。在32位世界中,它们是相同的,但是现在它们都不同了。

Linux安装了各种库,并在/ usr / lib和/ usr / include下包含了文件,因此易于查找和使用。当您安装XCode时,它会为MacOS,iOS,iPadOS,iWatchOS等安装SDK,并可以选择为版本安装批量。库和包含库的路径相当复杂,您需要一个工具来查找它们。

在MacOS中,程序必须在64位边界上启动,因此列表顶部附近有一个“ .align 2”指令。

在MacOS中,即使您没有从系统库中进行系统调用或收到链接器错误,也需要在系统库中进行链接。该示例Hello World程序使用软件中断而不是系统库中的API进行软件调用来进行系统调用,因此无需链接至该程序。

在MacOS中,默认入口点是_main,而在Linux中,默认入口点是_start。这是通过链接器的命令行参数进行更改的。

下面是简单的汇编语言程序,可在终端窗口中打印出“ Hello World”。有关这些指令和ARM处理器体系结构的所有细节,请查阅我的书。

// //汇编程序打印" Hello World!" //到标准输出。 // // X0-X2-linux函数服务的参数// X16-linux函数编号// .global _start //向链接器提供程序起始地址.align 2 //设置参数以打印hello world //然后调用Linux做到了。 _start:mov X0,#1 // 1 = StdOut adr X1,helloworld //要打印的字符串mov X2,#13 // //字符串的长度mov X16,#4输出字符串//设置参数以退出程序// //然后调用Linux进行操作。 mov X0,#0 //使用0返回代码mov X16,#1 //服务命令代码1终止该程序svc 0 0 //调用linux终止程序helloworld; 34 ;

这是makefile,汇编源代码的命令很简单,然后链接的命令则有点复杂。

HelloWorld:HelloWorld.o ld -macosx_version_min 11.0.0 -o HelloWorld HelloWorld.o -lSystem -syslibroot`xcrun -sdk macosx --show-sdk-path` -e _start -arch arm64 HelloWorld.o:HelloWorld.s为-o HelloWorld.o HelloWorld.s

xcrun命令是Apple运行或查找各种SDK的命令。这是运行它的一个示例:

stephensmith @ Stephens-MacBook-Air-2〜%xcrun -sdk macosx –show-sdk-path objc [42012]:AMSupportURLConnectionDelegate类在两个版本中都实现了? (0x1edb5b8f0)和?? (0x122dd02b8)。将使用两者之一。哪一个未定义。 objc [42012]:类AMSupportURLSession在两个版本中都实现了? (0x1edb5b940)和?? (0x122dd0308)。将使用两者之一。哪一个未定义。 objc [42013]:类AMSupportURLConnectionDelegate在两个版本中都实现了? (0x1edb5b8f0)和?? (0x1141942b8)。将使用两者之一。哪一个未定义。 objc [42013]:类AMSupportURLSession在两个版本中都实现了? (0x1edb5b940)和?? (0x114194308)。将使用两者之一。哪一个未定义。 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk stephensmith @ Stephens-MacBook-Air-2〜%

stephensmith @ Stephens-MacBook-Air-2第1章将-B设为-o HelloWorld.o HelloWorld.s objc [42104]:AMSupportURLConnectionDelegate类在两种方法中都实现了? (0x1edb5b8f0)和?? (0x1145342b8)。将使用两者之一。哪一个未定义。 objc [42104]:在这两种方法中都实现了AMSupportURLSession类。 (0x1edb5b940)和?? (0x114534308)。将使用两者之一。哪一个未定义。 ld -macosx_version_min 11.0.0 -o HelloWorld HelloWorld.o -lSystem -syslibroot`xcrun -sdk macosx –show-sdk-path` -e _start -arch arm64 stephensmith @ Stephens-MacBook-Air-2第1%./HelloWorld世界! stephensmith @ Stephens-MacBook-Air-2第1章

新的Apple M1 Macintoshes作为所有Apple Silicon的一部分运行ARM处理器,您可以运行标准的ARM 64位汇编语言。 LLVM是一个标准的开源开发工具,其中包含一个类似于GNU汇编器的汇编器。 MacOS的编程与Linux类似,因为两者均基于Unix,并且如果您熟悉Linux,则您的大部分知识都可以直接应用。