title: ARM: Why do I need to push/pop two registers at function calls?
body: <p>I understand that I need to push the Link Register at the beginning of a function call, and pop that value to the Program Couter before returning, so that the execution can carry one from where it was before the function call.</p>
  
  <p>What I don't understand is why most people do this by adding an extra register to the push/pop. For instance:</p>
  
  <pre><code>push {ip, lr}
  ...
  pop {ip, pc}
  </code></pre>
  
  <p>For instance, here's a Hello World in ARM, provided by the <a href="http://blogs.arm.com/software-enablement/139-hello-world-in-assembly/" rel="noreferrer">official ARM blog</a>:</p>
  
  <pre><code>.syntax unified
  
      @ --------------------------------
      .global main
  main:
      @ Stack the return address (lr) in addition to a dummy register (ip) to
      @ keep the stack 8-byte aligned.
      push    {ip, lr}
  
      @ Load the argument and perform the call. This is like 'printf("...")' in C.
      ldr     r0, =message
      bl      printf
  
      @ Exit from 'main'. This is like 'return 0' in C.
      mov     r0, #0      @ Return 0.
      @ Pop the dummy ip to reverse our alignment fix, and pop the original lr
      @ value directly into pc — the Program Counter — to return.
      pop     {ip, pc}
  
      @ --------------------------------
      @ Data for the printf calls. The GNU assembler's ".asciz" directive
      @ automatically adds a NULL character termination.
  message:
      .asciz  "Hello, world.\n"
  </code></pre>
  
  <p><strong>Question 1</strong>: what's the reason for the "dummy register" as they call it? Why not simply push{lr} and pop{pc}? They say it's to keep the stack 8-byte aligned, but ain't the stack 4-byte aligned?</p>
  
  <p><strong>Question 2</strong>: what register is "ip" (i.e., r7 or what?)</p>