文章目录
  1. 1. 前言
  2. 2. iOS ABI
    1. 2.1. iOS platform designers
    2. 2.2. iOS与官方arm64不同点
      1. 2.2.1. 参数传递
      2. 2.2.2. 可变参数
      3. 2.2.3. 基本C语言类型
      4. 2.2.4. 数据类型和内存对齐
  3. 3. 引用

前言

欢迎大家关注我的掘金主页,我后面会以掘金为主;有文章先发在掘金上,然后同步到自己博客上来。

上篇文章介绍arm64程序调用规则,这篇介绍iOS平台上的特定规则。

iOS ABI

在iOS平台上,基本是遵循上篇文章上的规则。但是也有几个不同规则。

iOS platform designers

  1. x18寄存器为平台保留,程序不可用。
  2. wchar_t类型是32bit, long类型是64bit。
  3. x29(FP:保存函数栈的基地址)必须总是有意义的。
  4. 空结构体,在函数调用的参数中被忽略。
    empty-Struct

iOS与官方arm64不同点

参数传递

  1. 在arm64标准中,当参数是通过栈传递时(比如参数超过8个),每个参数消耗8个字节的倍数。但是iOS中删除了这个要求。
    例如:
    1
    void two_stack_args(char w0, char w1, char w2, char w3, char w4, char w5, char w6, char w7, char s0, char s1) {}

s0在sp处占用1个字节,s1在sp + 1处占用1个字节。然后填充满足内存对齐(sp必须是16的倍数)。

  1. 在arm64标准中,当传递16字节对齐的参数时,从偶数寄存器xN开始。但是iOS中,没有这个要求。例如:
    1
    void large_type(int x0, __int128 x1_x2) {}

在iOS平台,参数x1_x2在x1和x2中传递;arm64标准里,参数应该在x2和x3中传递。

  1. 在arm64标准中,被调用者负责对少于32bits的参数进行0扩展或者标记;在iOS中,调用者负责扩展至32bits。

可变参数

iOS ABI和arm64标准完全不同。

  1. 可变参数中的匿名参数都是通过栈传递的。(每个可变参数分配8字节倍数栈空间,同时注意sp%16=0),固定参数传递方式跟arm64标准一致。
    由于参数传递方式不同,可变参数函数,是不能直接用函数指针赋值,然后当做固定参数函数调用。
    例如:
    1
    2
    3
    4
    5
    6
    7
    8
    typedef int __cdecl (*PInvokeFunc) (const char*, int);

    int test()
    {
    PInvokeFunc fp = (PInvokeFunc)printf;
    fp("Hello World: %d", 10); //不一定打印出Hello World: 10
    return 0;
    }

解决办法是:通过IL2CPP生成包装函数。

  1. C语言在函数调用之前,小于int类型的参数,进行提升。注意,栈空间上未填充的bit的值不确定(arm64标准里,寄存器和栈上未填充的bit值,也是不确定的)。
  2. va_list(可变参数函数里,获取可变参数列表的类型)就是char* 。

基本C语言类型

  1. long double是double(32bit)精度,而不是quad(64bit)精度。
  2. char 和 wchar_t 有符号的。

数据类型和内存对齐

Data type Size (in bytes) Natural alignment (in bytes)
BOOL, bool 1 1
char 1 1
short 2 2
int 4 4
long 8 8
long long 8 8
pointer 8 8
size_t 8 8
NSInteger 8 8
CFIndex 8 8
fpos_t 8 8
off_t 8 8

引用

  1. http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
  2. https://blog.csdn.net/adaptiver/article/details/80492292
  3. https://developer.apple.com/library/archive/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARM64FunctionCallingConventions.html
  4. https://stackoverflow.com/questions/35536515/variable-argument-function-bad-access-with-va-arg-at-ios-arm64

–EOF– 若无特别说明,本站文章均为原创,转载请保留链接,谢谢

文章目录
  1. 1. 前言
  2. 2. iOS ABI
    1. 2.1. iOS platform designers
    2. 2.2. iOS与官方arm64不同点
      1. 2.2.1. 参数传递
      2. 2.2.2. 可变参数
      3. 2.2.3. 基本C语言类型
      4. 2.2.4. 数据类型和内存对齐
  3. 3. 引用