caller和callee的使用方法

本文介绍了JavaScript中caller和callee的用途及应用场景。caller用于检查函数是否在顶层执行,callee则用于实现匿名函数的递归调用。通过实例展示了如何利用这两个特性进行函数调用的控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是caller:

先看官方定义的概念:Function对象的caller属性是对调用当前函数的函数的引用。如果该函数是从JavaScript程序的顶层调用的,caller的值就为null

看个例子:

function callerDemo() {
	if (callerDemo.caller == null) {
		return "在顶层执行";
	}
	else
	{
		return "被函数使用";
	}
}
function handleCaller(){
	alert(callerDemo());
}

caller有啥用:判断是否在顶层使用,也可以像抽象类一样,要求该函数必须在函数内执行

什么是callee;

概念:属性arguments.callee引用当前正在运行的函数。它给未命名的函数提供了一种自我引用的方式。该属性只在函数体内被定义。

看个例子:

var factorial = function(x) {
	if (x < 2) return 1;
	else return x * arguments.callee(x-1);
}
var y = factorial(5);// 返回 120 5*4*3*2*1=120

callee有啥用:匿名函数的递归

<think>好的,我需要回答用户关于ARM64架构中callercallee的概念及寄存器调用约定参数传递规则的问题。首先,我应该回顾用户提供的引用内容,看看是否有相关的信息可以直接使用。 根据引用[2],ARM64的参数传递规则是使用通用寄存器中的X0到X7作为参数寄存器,用于函数调用时的参数传递。这应该是参数传递规则的核心部分。此外,引用[3]提到矢量寄存器用于SIMD操作浮点运算,可能涉及浮点参数的传递方式。 接下来,我需要解释callercallee的概念。Caller是调用函数的代码,callee是被调用的函数。在调用约定中,caller需要保存某些寄存器的值,而callee需要保存其他寄存器的值,以防止寄存器被覆盖导致数据丢失。 在ARM64架构中,根据调用约定,X0到X7用于传递参数返回值。X8可能用作间接结果寄存器。X9到X15是临时寄存器,caller不需要保存它们,而callee可以自由使用。X19到X28是callee保存的寄存器,如果callee使用它们,必须保存原始值并在返回前恢复。X18是平台保留寄存器,X29是帧指针,X30是链接寄存器,用于保存返回地址。 对于浮点参数,矢量寄存器V0到V7可能用于传递浮点参数,而V8到V15是callee保存的。此外,栈的使用规则也很重要,当参数超过寄存器数量时,多余的参数需要通过栈传递,且栈需要对齐到16字节。 需要确保回答结构清晰,分点说明调用约定、参数传递规则、寄存器的分以及栈的使用,同时结合用户提供的引用内容,正确标注引用来源。最后生成相关问题,帮助用户进一步理解相关知识。</think>### ARM64调用约定详解 #### 一、CallerCallee基本概念 在ARM64架构中: - **Caller(调用者)**:主动发起函数调用的代码段,负责传递参数保存临时寄存器状态 - **Callee(被调用者)**:被调用的函数,负责保存/恢复自己的专用寄存器状态,并在完成后返回控制权[^2] #### 二、寄存器调用约定 寄存器分为四(X寄存器组): ```armasm X0-X7 : 参数传递与返回值寄存器(Caller管理) X8 : 间接结果寄存器(如返回大结构体地址) X9-X15 : 临时寄存器(Caller无需保存) X16-X17 : 平台保留寄存器(禁止用户使用) X18 : 平台保留寄存器(TLS相关) X19-X28 : Callee保存寄存器(使用前必须保存原值) X29 : 帧指针(FP) X30 : 链接寄存器(LR) SP : 栈指针 ``` #### 三、参数传递规则 1. **整型参数**: - 前8个参数通过X0-X7传递 - 超出部分通过栈传递(右→左顺序入栈) - 返回值存储在X0中,64位值使用X0,128位值使用X0+X1 2. **浮点参数**: - 使用矢量寄存器V0-V7传递 - 超出8个后使用栈传递 - SIMD矢量参数使用V0-V7的低64位[^3] 3. **混合参数传递示例**: ```c // 函数原型:void func(int a, float b, double c) // 对应寄存器: // X0 = a // S0 = b(单精度浮点) // D1 = c(双精度浮点) ``` #### 四、栈使用规范 1. 栈必须保持16字节对齐 2. 参数区需预留至少8个寄存器的空间(64字节) 3. 局部变量存储需满足: ```armasm sub sp, sp, #32 // 分配32字节栈空间 ... add sp, sp, #32 // 释放空间 ``` #### 五、保存规则对比 | 寄存器型 | 保存责任方 | 使用场景 | |------------|------------|-------------------------| | X19-X28 | Callee | 长期变量存储 | | X0-X7 | Caller | 参数传递 | | X9-X15 | 无需保存 | 临时计算 | | V8-V15 | Callee | 浮点/SIMD长期变量[^3] | #### 六、典型函数调用过程 1. Caller操作: - 保存X0-X7到栈(可选) - 设置X0-X7参数寄存器 - 使用`bl`指令跳转 2. Callee操作: ```armasm stp x29, x30, [sp, #-16]! // 保存FPLR mov x29, sp // 设置新FP stp x19, x20, [sp, #-16]! // 保存Callee寄存器 ... ldp x19, x20, [sp], #16 // 恢复寄存器 ldp x29, x30, [sp], #16 // 恢复FPLR ret // 返回 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值