飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 8370|回复: 8

[iOS] armv7、arm64传参研究

[复制链接]
  • TA的每日心情
    开心
    2016-6-16 14:07
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    发表于 2015-7-24 15:38:19 | 显示全部楼层 |阅读模式

    很久前的笔记,整理出来重新研究下


    测试设备:
    iPod Touch 5G
    iPad Air2


    1. ////////////////////////////////////////////////////////////////////////
    2. /// armv7传参研究
    3. ////////////////////////////////////////////////////////////////////////

    4. //---------------------------------------------------------------------
    5. int func(int a, int b, int c, int d, int e, int f)
    6. {
    7.     int ret = a + b + c + d + e + f;
    8.     return ret;
    9. }

    10. _func:
    11. Lfunc_begin0:

    12.         @DEBUG_VALUE: func:a <- R0     // 前4个参数放到r0 - r3
    13.         @DEBUG_VALUE: func:b <- R1
    14.         @DEBUG_VALUE: func:c <- R2
    15.         @DEBUG_VALUE: func:d <- R3
    16.         @DEBUG_VALUE: func:e <- [SP+0] // 第5参数
    17.         @DEBUG_VALUE: func:f <- [SP+4] // 第6参数

    18.         add        r0, r1
    19.         ldr.w        r12, [sp]      // 参数4
    20.         add        r0, r2
    21.         ldr.w        r9, [sp, #4]   // 参数5
    22.         add        r0, r3
    23.         add        r0, r12
    24.         add        r0, r9             // 最终结果累加到r0
    25.         @DEBUG_VALUE: func:ret <- R0
    26.         bx        lr                 // 返回调用方
    27. Lfunc_end0:
    28. //---------------------------------------------------------------------
    29. // 结论:
    30. // 1.可以看到7个参数以下,无需保存现场-因为压根用不到r7和lr
    31. // 2.前四参数:r0-r3  第五参数:[sp+0]  第六参数:[sp+4]


    32. // 上面结果似乎在我们意料之中!!
    33. //---------------------------------------------------------------------
    34. // 现在我们修改代码,多加入一个参数

    35. int func(int a, int b, int c, int d, int e, int f, int g)
    36. {
    37.     int ret = a + b + c + d + e + f + g;
    38.     return ret;
    39. }

    40. // 哈哈,这时候有看头了
    41. _func:
    42. Lfunc_begin0:

    43.         push        {r7, lr}
    44.         mov        r7, sp                        // 将r7指向sp
    45.         @DEBUG_VALUE: func:a <- R0
    46.         @DEBUG_VALUE: func:b <- R1
    47.         @DEBUG_VALUE: func:c <- R2
    48.         @DEBUG_VALUE: func:d <- R3
    49.         @DEBUG_VALUE: func:e <- [R7+8]
    50.         @DEBUG_VALUE: func:f <- [R7+12]
    51.         @DEBUG_VALUE: func:g <- [R7+16]

    52.         add        r0, r1
    53.         ldr.w        lr, [r7, #8]        // 参数5
    54.         add        r0, r2
    55.         ldr.w        r9, [r7, #12]       // 参数6
    56.         add        r0, r3
    57.         ldr.w        r12, [r7, #16]      // 参数7
    58.         add        r0, lr
    59.         add        r0, r9
    60.         add        r0, r12                 // 结果累加到r0
    61.         @DEBUG_VALUE: func:ret <- R0
    62.         pop        {r7, pc}
    63. Lfunc_end0:

    64. // 结论:
    65. // 1.开始压入r7和lr了
    66. // 2.r7-->sp
    67. // 2.第5参数从[r7+8]开始


    68. //---------------------------------------------------------------------
    69. 现在我们修改代码,再加入一个参数--ok现在8个参数了

    70. int func(int a, int b, int c, int d, int e, int f, int g, int h)
    71. {
    72.     int ret = a + b + c + d + e + f + g + h;
    73.     return ret;
    74. }

    75. // 下面开始变得好玩了,看好啦~~

    76. _func:
    77. Lfunc_begin0:

    78.         push        {r4, r7, lr}               // 保存现场
    79.         add        r7, sp, #4                     // 现在sp+4指向栈上r4的位置 --- 这里一个诀窍,就是看r7前有n个寄存器,后面的数值就是 n*4 (szieof(int))
    80.         @DEBUG_VALUE: func:a <- R0
    81.         @DEBUG_VALUE: func:b <- R1
    82.         @DEBUG_VALUE: func:c <- R2
    83.         @DEBUG_VALUE: func:d <- R3
    84.         @DEBUG_VALUE: func:e <- [R7+8]
    85.         @DEBUG_VALUE: func:f <- [R7+12]
    86.         @DEBUG_VALUE: func:g <- [R7+16]
    87.         @DEBUG_VALUE: func:h <- [R7+20]

    88.         add        r0, r1
    89.         add.w        lr, r7, #8                //  指向第5个参数地址
    90.         add        r0, r2
    91.         ldm.w        lr, {r4, r9, r12, lr}     // 一条指令取得剩下的参数
    92.         add        r0, r3
    93.         add        r0, r4
    94.         add        r0, r9
    95.         add        r0, r12
    96.         add        r0, lr
    97. Ltmp1:
    98.         @DEBUG_VALUE: func:ret <- R0
    99.         pop        {r4, r7, pc}                  // 恢复现场
    100. Ltmp2:
    101. Lfunc_end0:
    102. //---------------------------------------------------------------------

    103. // 结论:
    104. // 1.开始压入r7和lr了
    105. // 2.r7-->[sp + n*4]
    106. // 2.第5参数从[r7+8]开始



    107. ////////////////////////////////////////////////////////////////////////
    108. /// arm64传参研究
    109. ////////////////////////////////////////////////////////////////////////

    110. //---------------------------------------------------------------------
    111. // 先看看int型的
    112. int func(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l)
    113. {
    114.     int ret = a + b + c + d + e + f + g + h + i + j + k + l;
    115.     return ret;
    116. }

    117. _func:                                  ; @func
    118. Lfunc_begin0:

    119.         ;DEBUG_VALUE: func:a <- W0
    120.         ;DEBUG_VALUE: func:b <- W1
    121.         ;DEBUG_VALUE: func:c <- W2
    122.         ;DEBUG_VALUE: func:d <- W3
    123.         ;DEBUG_VALUE: func:e <- W4
    124.         ;DEBUG_VALUE: func:f <- W5
    125.         ;DEBUG_VALUE: func:g <- W6
    126.         ;DEBUG_VALUE: func:h <- W7
    127.         ;DEBUG_VALUE: func:i <- [SP+0]
    128.         ;DEBUG_VALUE: func:j <- [SP+4]
    129.         ;DEBUG_VALUE: func:k <- [SP+8]
    130.         ;DEBUG_VALUE: func:l <- [SP+12]

    131.         ldp        w9, w8, [sp, #8]   // ldp命令能一次获取给两个寄存器赋值,这里就给w8 w9赋值了
    132.         ldp         w11, w10, [sp]    // w10、w11赋值

    133.         add         w12, w1, w0       // 下面是各寄存器相加
    134.         add         w12, w12, w2
    135.         add         w12, w12, w3
    136.         add         w12, w12, w4
    137.         add         w12, w12, w5
    138.         add         w12, w12, w6
    139.         add         w12, w12, w7
    140.         add         w11, w12, w11
    141.         add         w10, w11, w10
    142.         add         w9, w10, w9
    143.         add         w0, w9, w8       // w0返回

    144.         ;DEBUG_VALUE: func:ret <- W0
    145.         ret                   // 调用ret返回函数
    146. Lfunc_end0:

    147. // 结论:
    148. // 1.int型(32bit)由w开头的寄存器操作,结果在w0返回
    149. // 2.前八个参数:w0-w7 后面开始栈传递


    150. //---------------------------------------------------------------------
    151. // 再看看long型的
    152. long func2(long a, long b, long c, long d, long e, long f, long g, long h, long i, long j, long k, long l)
    153. {
    154.     long ret = a + b + c + d + e + f + g + h + i + j + k + l;
    155.     return ret;
    156. }

    157. _func2:                                 ; @func2
    158. Lfunc_begin1:

    159.         ;DEBUG_VALUE: func2:a <- X0
    160.         ;DEBUG_VALUE: func2:b <- X1
    161.         ;DEBUG_VALUE: func2:c <- X2
    162.         ;DEBUG_VALUE: func2:d <- X3
    163.         ;DEBUG_VALUE: func2:e <- X4
    164.         ;DEBUG_VALUE: func2:f <- X5
    165.         ;DEBUG_VALUE: func2:g <- X6
    166.         ;DEBUG_VALUE: func2:h <- X7
    167.         ;DEBUG_VALUE: func2:i <- [SP+0] // 栈以0x8递增
    168.         ;DEBUG_VALUE: func2:j <- [SP+8]
    169.         ;DEBUG_VALUE: func2:k <- [SP+16]
    170.         ;DEBUG_VALUE: func2:l <- [SP+24]

    171.         ldp        x9, x8, [sp, #16]  // ldp命令一次对两个寄存器操作
    172.         ldp         x11, x10, [sp]

    173.         add         x12, x1, x0       // 下面是各寄存器相加
    174.         add         x12, x12, x2
    175.         add         x12, x12, x3
    176.         add         x12, x12, x4
    177.         add         x12, x12, x5
    178.         add         x12, x12, x6
    179.         add         x12, x12, x7
    180.         add         x11, x12, x11
    181.         add         x10, x11, x10
    182.         add         x9, x10, x9
    183.         add         x0, x9, x8       // x0返回
    184.         ;DEBUG_VALUE: func2:ret <- X0
    185.         ret                   // 调用ret返回函数
    186. Lfunc_end1:

    187. // 结论:
    188. // 1.long型(64bit)由x开头的寄存器操作,结果在x0返回
    189. // 2.前八个参数:x0-x7 后面开始栈传递

    190. //---------------------------------------------------------------------
    复制代码


    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    10 小时前
  • 签到天数: 610 天

    [LV.9]以坛为家II

    发表于 2015-7-24 18:53:28 | 显示全部楼层
    不明觉厉!{:soso_e179:}
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2015-8-2 16:07
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2015-7-25 22:25:31 | 显示全部楼层
    真厉害,感觉在情理之中,貌似与win下x64的传参有类似的地方
    PYG19周年生日快乐!
  • TA的每日心情
    无聊
    2016-10-10 10:27
  • 签到天数: 26 天

    [LV.4]偶尔看看III

    发表于 2015-7-26 10:48:47 | 显示全部楼层
    {:soso_e179:} 学习了
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2019-3-1 23:51
  • 签到天数: 559 天

    [LV.9]以坛为家II

    发表于 2015-7-28 19:41:43 | 显示全部楼层
    谢谢楼主分享.
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2017-9-3 08:13
  • 签到天数: 245 天

    [LV.8]以坛为家I

    发表于 2015-8-25 09:46:46 | 显示全部楼层
    学习了,支持原创
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2023-9-19 08:48
  • 签到天数: 35 天

    [LV.5]常住居民I

    发表于 2015-9-15 17:43:01 | 显示全部楼层
    谢谢分享,过来看看
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2021-1-14 22:27
  • 签到天数: 32 天

    [LV.5]常住居民I

    发表于 2015-10-10 16:33:48 | 显示全部楼层
    楼主太厉害喇,又学习到知识了。
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2021-7-10 23:06
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2021-7-29 11:42:56 | 显示全部楼层
    留个名慢慢消化
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表