测试设备:

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 后面开始栈传递 
//---------------------------------------------------------------------



你可能感兴趣的文章

评论区

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。