【发布时间】:2015-06-19 21:19:00
【问题描述】:
我正在尝试用 asm 实现替换某些方法。目标是 iOS 上的 arm64(iPhone 5S 或更新版本)。我想使用专用的汇编器文件,因为内联汇编器会带来额外的开销,而且相当 cumbersome to use with A64 memory offsets。
Internet 上没有太多关于此的文档,所以我有点不确定我该怎么做。因此,我将描述我将函数移动到 ASM 所遵循的过程。
本题的候选函数是一个 256 位整数比较函数。
UInt256.h
@import Foundation;
typedef struct {
uint64_t value[4];
} UInt256;
bool eq256(const UInt256 *lhs, const UInt256 *rhs);
Bridging-Header.h
#import "UInt256.h"
Reference implementation (Swift)
let result = x.value.0 == y.value.0
&& x.value.1 == y.value.1
&& x.value.2 == y.value.2
&& x.value.3 == y.value.3
UInt256.s
.globl _eq256
.align 2
_eq256:
ldp x9, x10, [x0]
ldp x11, x12, [x1]
cmp x9, x11
ccmp x10, x12, 0, eq
ldp x9, x10, [x0, 16]
ldp x11, x12, [x1, 16]
ccmp x9, x11, 0, eq
ccmp x10, x12, 0, eq
cset x0, eq
ret
我找到的资源
Procedure Call Standard for the ARM 64-bit Architecture (AArch64) 文档的第 5.1.1 节解释了过程调用期间每个寄存器的用途。
iOS 特定 deviations.
iOS Assembler Directives.
问题
我使用 XCTest 测试了代码,创建了两个随机数,在它们上运行 Swift 和 Asm 实现,并验证两者报告的结果相同。代码似乎是正确的。
在 asm 文件中:
.align似乎是为了优化 - 这真的有必要吗,如果是,要对齐的正确值是什么?-
是否有任何来源清楚地解释了我的特定函数签名的调用约定?
一个。我怎么知道输入实际上是通过
x0和x1传递的?b.我怎么知道在
x0中传递输出是正确的?c。我怎么知道破坏
x9-x12和状态寄存器是安全的?d。当我从 C 而不是 Swift 调用该函数时,它的调用方式是否相同?
“间接结果位置寄存器”对于ARM文档中的
r8寄存器描述是什么意思?除了
.globl,我还需要其他汇编指令吗?当我设置断点时,调试器似乎对它的实际位置感到困惑,显示不正确的行等。我做错了什么吗?
【问题讨论】:
标签: ios swift assembly calling-convention arm64