Page 149 - ARM 64 Bit Assembly Language
P. 149

Structured programming 135


                              Listing 5.27 A function call using stp to push arguments on the stack.
                                .
                    1           . .
                    2         // marshaling onto the stack.
                    3         ldr    w9, [x19, #(4*7)]      // w9 = p
                    4         ldr    w10, [x19, #(4*8)]     // w10 = q
                    5         ldr    w11, [x19, #(4*9)]     // w11 = r
                    6         stp    x9, x10, [sp, #-32]!   // 8 bytes per parameter
                    7         str    x11, [sp, #16]
                    8
                    9         // call printf
                   10         bl     printf
                   11
                   12         // pop p, q, and r from the stack
                   13         add    sp, sp, #32
                              .
                   14         . .



                     of thirty two bytes (each argument required 8 bytes, but the stack is only allowed to grow or
                     shrink in multiples of 16 bytes). Therefore, all we need to do is add thirty two to the stack
                     pointer, thereby restoring its original value.


                     5.4.6 Writing subroutines


                     We have looked at the conventions that programmers use to pass arguments when calling
                     functions. Now we will examine these same conventions from the point of view of the func-
                     tion being called. Because of the calling conventions, the programmer writing a function can
                     assume that

                     •   the first eight parameters are in x0–x7,
                     •   any additional parameters can be accessed with ldr Rd, [sp, #offset],
                     •   the calling function will remove parameters from the stack, if necessary,
                     •   if the function return type is not void, then they must ensure that the return value is in x0
                         (and possibly x1, x2,and x3, if the function returns multiple values), and
                     •   the return address will be in x30.

                     Also because of the conventions, there are certain registers that can be used freely, while oth-
                     ers must be preserved or restored so that the calling function can continue operating correctly.
                     Registers which can be used freely are referred to as volatile, and registers which must be pre-
                     served or restored before returning are referred to as non-volatile. When writing a subroutine
                     (function),
                     •   registers x0-x18 are volatile,
   144   145   146   147   148   149   150   151   152   153   154