Arm 非常重要的BASC臂装配问题(添加、比较)
TLDR:bx lr到底做什么? 我很难理解以下两个例子: *添加示例: 我理解代码“addr0,r0,r1”将r1添加到r1,并将其存储到寄存器0。我不明白的是代码“bx lr”如何知道 返回r0而不显式声明r0 比较示例:Arm 非常重要的BASC臂装配问题(添加、比较),arm,pi,Arm,Pi,TLDR:bx lr到底做什么? 我很难理解以下两个例子: *添加示例: 我理解代码“addr0,r0,r1”将r1添加到r1,并将其存储到寄存器0。我不明白的是代码“bx lr”如何知道 返回r0而不显式声明r0 比较示例: 同样,我理解代码“BGT r0_Gt”在r0>r1时进行比较,如果这是真的,代码将跳到r0_Gt:但是,bx lr如何知道如何返回正确的值?它是由使用的ABI定义的;对于ARM,这是EABI,在“5.4结果返回”中说明 小于4字节的基本数据类型是零或符号扩展到一个字
同样,我理解代码“BGT r0_Gt”在r0>r1时进行比较,如果这是真的,代码将跳到r0_Gt:但是,bx lr如何知道如何返回正确的值?它是由使用的ABI定义的;对于ARM,这是EABI,在“5.4结果返回”中说明
- 小于4字节的基本数据类型是零或符号扩展到一个字,并以r0返回
bx-lr
根本不返回任何寄存器,它只是将控制权传递回调用者(在lr
寄存器的地址中),而不修改除pc
之外的任何其他寄存器
然后,调用方根据调用约定知道,返回时,返回值将在r0寄存器中(取决于返回值的确切类型和平台的调用约定)。BX只是表示分支交换,它执行分支,并且如果该体系结构支持,它可以在arm/thumb之间切换模式。LR是寄存器14的快捷方式,就这么简单。分支到r14中的地址 如果查看bl指令,您会发现r14将设置为bl指令后的地址,即函数调用的返回地址
bx lr(或mov pc,如果您不需要更改模式并且处于arm模式,lr也可以工作)是您在arm中进行函数调用的方式。处理器对上下文的概念很少(抽象意义上)。它不知道它来自何处,寄存器用于什么,或者它是否在函数调用/子例程中。高级语言和编译器确实知道这一点,并使用一些通用标准使事情变得更简单 非常少的操作确实有一个特殊的、明确的目的。BL指令既更新“下一条要执行的指令”(也称为PC或R15),又神奇地更新R14(链接寄存器) 异常(在V7-A中)会改变周围的一些堆核心寄存器,包括通常用于访问堆栈的寄存器和链接寄存器。这意味着异常可以在不丢失正在发生的其他一切的情况下发生。Cortex M的做法不同,实际上使用堆栈来帮助银行业务(将R14设置为“神奇值”,以指示最近的调用是否为异常) 除非指令与特定寄存器(特别是CPSR)交互,否则它可能不关心上下文。某些操作(与安全相关)将受到限制,因此它们只能在特权状态下发生-这最终用于阻止用户应用程序访问操作系统,但通常与访问非常特定的控制寄存器有关