为什么ARM会说“链接寄存器支持快速的叶子函数调用"? [英] Why does ARM say that "A link register supports fast leaf function calls"

查看:75
本文介绍了为什么ARM会说“链接寄存器支持快速的叶子函数调用"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我遇到了链接寄存器和叶子函数的概念.

I have came across the concepts of link register and leaf functions recently.

我从以前的SO阅读中了解到,LR告诉执行期间代码先前在哪里.我还知道叶子函数是在函数调用层次结构末尾出现的函数.

I understand from previous SO reads that the LR tells where the code was previously during execution. I also got to know that a leaf function is a function which comes at the end of the function call hierarchy.

ARM维基百科页面上说:

链接寄存器支持快速的叶子函数调用.

A link register supports fast leaf function calls.

为什么这样的说法是正确的?我看了《 ARMARM》(体系结构参考手册),链接寄存器上的信息很少.

Why is this claim true? I looked at the ARMARM (Architecture Reference Manual), and the information on the link register is minimal.

推荐答案

在某些体系结构(例如x86,x86_64)上,函数的返回地址始终存储在堆栈中,调用函数意味着访问主内存:

On some architectures (such as x86, x86_64), the return address of a function is always stored on the stack and calling a function implies accessing the main memory:

  • 调用时写入堆栈;

  • a write to the stack when calling;

返回时从堆栈读取.

相反,如果您的体系结构/ABI可以在不使用主存储器的情况下跳转/返回,并且被调用方的参数和返回值也可以在寄存器中传递,则可以在不使用叶函数的情况下进行调用和返回涉及RAM.

In contrast, if your architecture/ABI can jump/return without using the main memory and the parameters and return values of the callee can be passed in registers as well, the call and return to/from leaf functions can be done without involving RAM.

如果叶子功能足够简单,则可能完全不动RAM即可执行:

If the leaf function is simple enough, it might execute without touching RAM at all:

int callee(int a, int b)
{
  return a + b;
}

int caller(int a, int b, int c, int d)
{
  return callee(a,b) + calle(c,d);
}

给出(每个函数由 clang -target arm-eabi -S -o- -O3 分别编译):

gives (each function compiled separately by clang -target arm-eabi -S -o- -O3):

callee:
  add   r0, r1, r0
  bx    lr
caller:
  .save {r4, r5, r6, r10, r11, lr}
  push  {r4, r5, r6, r10, r11, lr}
  .setfp    r11, sp, #16
  add   r11, sp, #16
  mov   r4, r3
  mov   r5, r2
  bl    callee
  mov   r6, r0
  mov   r0, r5
  mov   r1, r4
  bl    callee
  add   r0, r0, r6
  pop   {r4, r5, r6, r10, r11, lr}
  bx    lr

注意我们如何避免访问 caller 的核心和 calee 的内存.

Notice how we can avoid accessing the memory in the core of caller and in calee.

这篇关于为什么ARM会说“链接寄存器支持快速的叶子函数调用"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆