在本系列中的第一条上文章中使用汇编语言开发Apple Silicon Macs,我建立了一个简单的框架ASMattic,可用作开发ARM汇编语言例程的基础。在此,我提供了一个简短而简单的演示,可以调用装配例程并获得其结果。本文首先通过解释ARM64处理器的寄存器架构来解释写自己的例程的机制。
在这第一篇文章中,我发出了一款外部双级Multadd(Double,Double,Double)的C包装器来调用_Multadd:str lr,[sp,#-16]的汇编语言例程! FMADD D0,D0,D1,D2 LDR LR,[SP],#16 RET
踩通过组装线,首先保存一组寄存器,执行我想要的浮点操作,恢复寄存器并返回。对于任何一个有意义的,您首先需要了解ARM64处理器的寄存器架构。
处理器有三种主要类型的寄存器:通用,浮点(包括SIMD)和特殊。当调用和运行这样的例程时,您最关心前两个,这在ARM的过程调用标准(下面参考文献)和Apple的特定于平台文档(参考文献)中详细解释。
有31个通用寄存器,每个寄存器可以用于64位或32位值。当使用64位时,它们将命名为x0至x30,并且32位为w30到w30。
存在32个浮点寄存器,每个浮点数可以用于128位值作为V0至V31,64位为D0至D31,以及32位为S0至S31。
为简单起见,在本系列中,我将默认为不同的整数和浮点使用64位值。这意味着我将最常用的寄存器是x和d系列,如上面的例子。在更高的语言等价物中,它们等同于C型Long,指针,SWIFT INT,C双倍和SWIFT双倍的数据。
这两种类型,X0-X7和D0-D7中的每一个中的前八个寄存器用于将参数传递给装配功能,并且第一个X0和D0用于返回组装例程的结果。它们是按顺序使用的:第一个非浮点参数将在X0中传递X0,X1中的第二个,等等;第一个浮点参数将在D0中传递,第二个浮点数为D1等。
重要的是要记住,这些是根据寄存器组使用的。对于Extern双磁带的C包装器(长,双,长,双)第一个长度将在X0中传递,D0中的第一个双倍,X1中的第二个长,D1中的第二个双倍,结果返回在D0中,因为它是一个双重的。
这是将参数传递给装配例程的最简单方法,其中使用该值,并将其放置在寄存器中,准备好用于访问的例程:“按值呼叫”(或按值传递))。在X0或D0中返回的唯一结果也是单个值。
传递阵列,结构和其他不能简单地放入单个寄存器的参数需要不同的方法,其中传递给数据的指针:“通过引用调用”。这也用于使例程返回多个结果:当参数传递为指向浮点数的指针时,例如,如果例程更改该指针引用的值,则可以使用该值的值调用该例程的代码。
让我们假设浮点程需要三个代表x,y和z协调的双打,并且我希望它返回三个,表示转换为投影空间的协调的三倍。由于只有一个浮点数可以返回,因此在寄存器D0中,我们可以通过参考,extern void变换(* double,* double,* double)通过那些通过引用来传递那些协调
在SWIFT中,我们可能会又称为变换(& x,& y,& z)来传递那些双打的地址。
在组装例程中,按值调用最简单,因为该值可直接从指定的寄存器提供。通过引用呼叫有点复杂,但是,如在例程可以访问值之前,它首先必须从通过的地址加载它们。这就是我的下一篇文章开始的地方。
Apple硅的代码与Asmattic App(上一篇关于此博客上的文章)手术呼叫标准用于APS 64位架构(ARM)从Github编写ARM64代码(Apple)Stephen Smith(2020)编程为64- 位ARM汇编语言,APRESS,ISBN 978 1 4842 5880 4.Daniel KUSSWURM(2020)现代ARM汇编语言编程,APRess,ISBN 978 1 4842 6266 5. ARM64指令集参考(ARM)。 发布在Mac,技术和标记的Apple硅,臂,汇编器,汇编语言,M1,Xcode。 书签永久链接。