Page 141 - ARM 64 Bit Assembly Language
P. 141

Structured programming 127


                                  Listing 5.20 Calling scanf and printf in AArch64 assembly.

                    1         .data
                    2  str1:  .asciz  "%d"
                    3  str2:  .asciz  "You entered %d\n"
                    4  n:     .word  0
                    5         .text
                    6         .type  main, %function
                    7         .global main
                    8  main:
                    9         stp    x29, x30, [sp, #-16]!  // push FP, LR onto stack
                   10         adr    x0, str1               // x0 = &str1
                   11         adr    x1, n                  // x1 = &n
                   12         bl     scanf                  // scanf("%d",&n)
                   13         adr    x0, str2               // x0 = &str2
                   14         adr    x1, n                  // x1 = &n
                   15         ldr    w1, [x1]               // w1 = n
                   16         bl     printf                 // print message
                   17         mov    w0, #0                 // load return value
                   18         ldp    x29, x30, [sp], #16    // pop FP, LR from stack
                   19         ret                           // return from main
                   20         .size  main, (. - main)



                     •   The first eight parameters go in registers x0-x7.
                     •   Any remaining parameters are pushed to the stack (in reverse order).

                     If the subroutine returns a value, then the value is stored in x0 before the function returns to
                     its caller. Calling a subroutine in AArch64 assembly usually requires several lines of code.
                     The number of lines required depends on how many arguments the subroutine requires, and
                     where the data for those arguments are stored. Some variables may already be in the correct
                     register. Others may need to be moved from one register to another. Still others may need to
                     be loaded from memory into a register or loaded and then stored to the stack. Careful pro-
                     gramming is required to minimize the amount of work that must be done just to move the
                     subroutine arguments into their required locations.

                     The AArch64 register set was introduced in Chapter 3. Some registers have special purposes
                     that are dictated by the hardware design. Others have special purposes that are dictated by
                     programming conventions. Programmers follow these conventions so that their subroutines
                     are compatible with each other. These conventions are simply a set of rules for how regis-
                     ters should be used. In AArch64 assembly, all of the registers have alternate names that can
                     be used to help remember the rules for using them. Fig. 5.1 shows an expanded view of the
                     AArch64 registers, including their alternate names and conventional use.
   136   137   138   139   140   141   142   143   144   145   146