测试设备:
iPod Touch 5G
iPad Air2
//////////////////////////////////////////////////////////////////////// /// armv7传参研究 //////////////////////////////////////////////////////////////////////// //--------------------------------------------------------------------- int func(int a, int b, int c, int d, int e, int f) { int ret = a + b + c + d + e + f; return ret; } _func: Lfunc_begin0: @DEBUG_VALUE: func:a <- R0 // 前4个参数放到r0 - r3 @DEBUG_VALUE: func:b <- R1 @DEBUG_VALUE: func:c <- R2 @DEBUG_VALUE: func:d <- R3 @DEBUG_VALUE: func:e <- [SP+0] // 第5参数 @DEBUG_VALUE: func:f <- [SP+4] // 第6参数 add r0, r1 ldr.w r12, [sp] // 参数4 add r0, r2 ldr.w r9, [sp, #4] // 参数5 add r0, r3 add r0, r12 add r0, r9 // 最终结果累加到r0 @DEBUG_VALUE: func:ret <- R0 bx lr // 返回调用方 Lfunc_end0: //--------------------------------------------------------------------- // 结论: // 1.可以看到7个参数以下,无需保存现场-因为压根用不到r7和lr // 2.前四参数:r0-r3 第五参数:[sp+0] 第六参数:[sp+4] // 上面结果似乎在我们意料之中!! //--------------------------------------------------------------------- // 现在我们修改代码,多加入一个参数 int func(int a, int b, int c, int d, int e, int f, int g) { int ret = a + b + c + d + e + f + g; return ret; } // 哈哈,这时候有看头了 _func: Lfunc_begin0: push {r7, lr} mov r7, sp // 将r7指向sp @DEBUG_VALUE: func:a <- R0 @DEBUG_VALUE: func:b <- R1 @DEBUG_VALUE: func:c <- R2 @DEBUG_VALUE: func:d <- R3 @DEBUG_VALUE: func:e <- [R7+8] @DEBUG_VALUE: func:f <- [R7+12] @DEBUG_VALUE: func:g <- [R7+16] add r0, r1 ldr.w lr, [r7, #8] // 参数5 add r0, r2 ldr.w r9, [r7, #12] // 参数6 add r0, r3 ldr.w r12, [r7, #16] // 参数7 add r0, lr add r0, r9 add r0, r12 // 结果累加到r0 @DEBUG_VALUE: func:ret <- R0 pop {r7, pc} Lfunc_end0: // 结论: // 1.开始压入r7和lr了 // 2.r7-->sp // 2.第5参数从[r7+8]开始 //--------------------------------------------------------------------- 现在我们修改代码,再加入一个参数--ok现在8个参数了 int func(int a, int b, int c, int d, int e, int f, int g, int h) { int ret = a + b + c + d + e + f + g + h; return ret; } // 下面开始变得好玩了,看好啦~~ _func: Lfunc_begin0: push {r4, r7, lr} // 保存现场 add r7, sp, #4 // 现在sp+4指向栈上r4的位置 --- 这里一个诀窍,就是看r7前有n个寄存器,后面的数值就是 n*4 (szieof(int)) @DEBUG_VALUE: func:a <- R0 @DEBUG_VALUE: func:b <- R1 @DEBUG_VALUE: func:c <- R2 @DEBUG_VALUE: func:d <- R3 @DEBUG_VALUE: func:e <- [R7+8] @DEBUG_VALUE: func:f <- [R7+12] @DEBUG_VALUE: func:g <- [R7+16] @DEBUG_VALUE: func:h <- [R7+20] add r0, r1 add.w lr, r7, #8 // 指向第5个参数地址 add r0, r2 ldm.w lr, {r4, r9, r12, lr} // 一条指令取得剩下的参数 add r0, r3 add r0, r4 add r0, r9 add r0, r12 add r0, lr Ltmp1: @DEBUG_VALUE: func:ret <- R0 pop {r4, r7, pc} // 恢复现场 Ltmp2: Lfunc_end0: //--------------------------------------------------------------------- // 结论: // 1.开始压入r7和lr了 // 2.r7-->[sp + n*4] // 2.第5参数从[r7+8]开始 //////////////////////////////////////////////////////////////////////// /// arm64传参研究 //////////////////////////////////////////////////////////////////////// //--------------------------------------------------------------------- // 先看看int型的 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) { int ret = a + b + c + d + e + f + g + h + i + j + k + l; return ret; } _func: ; @func Lfunc_begin0: ;DEBUG_VALUE: func:a <- W0 ;DEBUG_VALUE: func:b <- W1 ;DEBUG_VALUE: func:c <- W2 ;DEBUG_VALUE: func:d <- W3 ;DEBUG_VALUE: func:e <- W4 ;DEBUG_VALUE: func:f <- W5 ;DEBUG_VALUE: func:g <- W6 ;DEBUG_VALUE: func:h <- W7 ;DEBUG_VALUE: func:i <- [SP+0] ;DEBUG_VALUE: func:j <- [SP+4] ;DEBUG_VALUE: func:k <- [SP+8] ;DEBUG_VALUE: func:l <- [SP+12] ldp w9, w8, [sp, #8] // ldp命令能一次获取给两个寄存器赋值,这里就给w8 w9赋值了 ldp w11, w10, [sp] // w10、w11赋值 add w12, w1, w0 // 下面是各寄存器相加 add w12, w12, w2 add w12, w12, w3 add w12, w12, w4 add w12, w12, w5 add w12, w12, w6 add w12, w12, w7 add w11, w12, w11 add w10, w11, w10 add w9, w10, w9 add w0, w9, w8 // w0返回 ;DEBUG_VALUE: func:ret <- W0 ret // 调用ret返回函数 Lfunc_end0: // 结论: // 1.int型(32bit)由w开头的寄存器操作,结果在w0返回 // 2.前八个参数:w0-w7 后面开始栈传递 //--------------------------------------------------------------------- // 再看看long型的 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) { long ret = a + b + c + d + e + f + g + h + i + j + k + l; return ret; } _func2: ; @func2 Lfunc_begin1: ;DEBUG_VALUE: func2:a <- X0 ;DEBUG_VALUE: func2:b <- X1 ;DEBUG_VALUE: func2:c <- X2 ;DEBUG_VALUE: func2:d <- X3 ;DEBUG_VALUE: func2:e <- X4 ;DEBUG_VALUE: func2:f <- X5 ;DEBUG_VALUE: func2:g <- X6 ;DEBUG_VALUE: func2:h <- X7 ;DEBUG_VALUE: func2:i <- [SP+0] // 栈以0x8递增 ;DEBUG_VALUE: func2:j <- [SP+8] ;DEBUG_VALUE: func2:k <- [SP+16] ;DEBUG_VALUE: func2:l <- [SP+24] ldp x9, x8, [sp, #16] // ldp命令一次对两个寄存器操作 ldp x11, x10, [sp] add x12, x1, x0 // 下面是各寄存器相加 add x12, x12, x2 add x12, x12, x3 add x12, x12, x4 add x12, x12, x5 add x12, x12, x6 add x12, x12, x7 add x11, x12, x11 add x10, x11, x10 add x9, x10, x9 add x0, x9, x8 // x0返回 ;DEBUG_VALUE: func2:ret <- X0 ret // 调用ret返回函数 Lfunc_end1: // 结论: // 1.long型(64bit)由x开头的寄存器操作,结果在x0返回 // 2.前八个参数:x0-x7 后面开始栈传递 //---------------------------------------------------------------------
发表评论