armv7、arm64传参研究
很久前的笔记,整理出来重新研究下
测试设备:
iPod Touch 5GiPad 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 <- // 第5参数
@DEBUG_VALUE: func:f <- // 第6参数
add r0, r1
ldr.w r12, // 参数4
add r0, r2
ldr.w r9, // 参数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第五参数:第六参数:
// 上面结果似乎在我们意料之中!!
//---------------------------------------------------------------------
// 现在我们修改代码,多加入一个参数
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 <-
@DEBUG_VALUE: func:f <-
@DEBUG_VALUE: func:g <-
add r0, r1
ldr.w lr, // 参数5
add r0, r2
ldr.w r9, // 参数6
add r0, r3
ldr.w r12, // 参数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参数从开始
//---------------------------------------------------------------------
现在我们修改代码,再加入一个参数--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 <-
@DEBUG_VALUE: func:f <-
@DEBUG_VALUE: func:g <-
@DEBUG_VALUE: func:h <-
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-->
// 2.第5参数从开始
////////////////////////////////////////////////////////////////////////
/// 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 <-
;DEBUG_VALUE: func:j <-
;DEBUG_VALUE: func:k <-
;DEBUG_VALUE: func:l <-
ldp w9, w8, // ldp命令能一次获取给两个寄存器赋值,这里就给w8 w9赋值了
ldp w11, w10, // 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 <- // 栈以0x8递增
;DEBUG_VALUE: func2:j <-
;DEBUG_VALUE: func2:k <-
;DEBUG_VALUE: func2:l <-
ldp x9, x8, // ldp命令一次对两个寄存器操作
ldp x11, x10,
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 后面开始栈传递
//---------------------------------------------------------------------
不明觉厉!{:soso_e179:} 真厉害,感觉在情理之中,貌似与win下x64的传参有类似的地方 {:soso_e179:} 学习了 谢谢楼主分享. 学习了,支持原创 谢谢分享,过来看看 楼主太厉害喇,又学习到知识了。 留个名慢慢消化
页:
[1]