-1

I understand that the Link register is used to store the return address after subroutine completes.

This avoids the need to store the return address on stack and return address can be directly copied from LR to PC .This can save some time due to memory access.

But how this works in case of multiple function calls, say F1() calls F2(),F2() calls F3() and F3() calls F4(). Still in this scenario we need to store the previous LR value on the stack memory and will be reading after that.

So is the LR mainly significant for leaf functions.

artless noise
  • 21,212
  • 6
  • 68
  • 105
akumar
  • 39
  • 7
  • as with any register that needs to be preserved from one call to another (r4,r5, etc) you put it on the stack. compile a trival program int fun ( int a) { return(more_fun(a)+1); } and you can see this in action. – old_timer Dec 25 '22 at 21:23
  • lr is the return address just like other isa+calling convention use a register. you get a little performance savings on functions that are leaf functions or that have a tail call optimization (remove the +1 and see if you can get the compiler to optimize that). – old_timer Dec 25 '22 at 21:25
  • it is a design choice, nothing more. one designer/team does things one way, another another. using registers for calling and returning vs the stack for everything like x86 in the old days, there is a performance improvement in some cases, and the stack based performs better in other cases. – old_timer Dec 25 '22 at 21:26
  • There is absolutely nothing semantically different between ARM32 and ARM64. The register numbers are different as there are more registers. However, the ideas of what a compiler does to create stack slots are the same. – artless noise Dec 28 '22 at 17:26

1 Answers1

0

In ARM(64) x30 = LR, x29 = FP, X31 = SP.

When a function needs to call other (non-inlined) functions, the caller will typically save both the previous frame pointer and previous link register to stack:

   stp     x29, x30, [sp, #-16]!  // store FP and LR to stack
   mov     x29, sp; // memorize the old FP (for debugging)
   ...
   bl foo
   ldp x29,x30, [sp], #16. // restore old FP, LR
   ret

As speculated, one does save the trouble of storing the frame pointer and LR on leaf functions.

(Clang can be also compiled with -fomit-frame-pointer, which saves 1-2 instructions, but still requires to store and restore the Link Register)

str     x30, [sp, #-16]!                // 8-byte Folded Spill
bl      foo
ldr     x30, [sp], #16                  // 8-byte Folded Reload
ret

The leaf function can simply return:

ret
Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57