title: Aarch64 Frame pointer
body: <p>I saw this code on page 120 of ArmV8 Programmer's Guide:</p>
  
  <pre><code>foo//
  SUB SP, SP, #0x30 
  STR W0, [SP, #0x2C] 
  STR W1, [SP, #0x28] 
  STR D0, [SP, #0x20] 
  STR D1, [SP, #0x18] 
  LDR W0, [SP, #0x2C] 
  STR W0, [SP, #0] 
  LDR W0, [SP, #0x28] 
  STR W0, [SP, #4] 
  LDR W0, [SP, #0x20] 
  STR W0, [SP, #8] 
  LDR W0, [SP, #0x18] 
  STR W0, [SP, #10] 
  LDR X9, [SP, #0x0] 
  STR X9, [X8, #0] 
  LDR X9, [SP, #8] 
  STR X9, [X8, #8] 
  LDR X9, [SP, #0x10] 
  STR X9, [X8, #0x10] 
  ADD SP, SP, #0x30 
  RET
  
  bar//
  STP X29, X30, [SP, #0x10]! 
  MOV X29, SP
  SUB SP, SP, #0x20
  ADD X8, SP, #8
  MOV W0, WZR
  ORR W1, WZR, #1
  FMOV D0, #1.00000000
  FMOV D1, #2.00000000
  BL foo:
  ADRP X8, {PC}, 0x78
  ADD X8, X8, #0
  LDR X9, [SP, #8]
  STR X9, [X8, #0]
  LDR X9, [SP, #0x10]
  STR X9, [X8, #8]
  LDR X9, [SP, #0x18]
  STR X9, [X8, #0x10]
  MOV SP, X29
  LDP X20, X30, [SP], #0x10
  RET
  </code></pre>
  
  <p>My question is regarding to following instruction at the end of bar routine:</p>
  
  <pre><code>LDP X20, X30, [SP], #0x10
  </code></pre>
  
  <p>LDP is for loading pair of registers from stack and restriction for this instruction will not allow loading to registers at that distance.</p>
  
  <p>First, why this line can be valid ?
  Second, why FP is loaded into x20 ? Isn't it supposed to load into x29 ?</p>
  
  <p>From ARM Procedure call standard :</p>
  
  <blockquote>
    <p>Each frame shall link to the frame of its caller by means of a frame record of two 64-bit values on the stack</p>
  </blockquote>
  
  <p>Of course it also mentions cases which these requirements are not mandatory, but in this case FP seems to be not valid because it is pointing to sp - 0x10 which which has fp and lr .</p>