/* 
 * File:        array.s
 * Description: This program illustrates array access.
 *              It reads the number of entries (up to 100).
 *              Then it prints the numbers in reverse.
 */
        .arch   armv8-a

        .global main

        .text
        .align  2
main:                              // The main function
        stp     fp, lr, [sp,-16]!  
        mov fp, sp
        
        // Read the number of numbers
        adr     x0, prompt1        // Pass the prompt in x0
        bl      printf             // Call printf
        
        adr     x0, infmt          // Pass the input format in x0
        adr     x1, n              // Pass the address of n in x1
        bl      scanf              // Call scanf

        // The loop control is stored in x19
        // n is stored in x20
        // Because we are calling printf and scanf, we need registers
        // that are preserved by the function calls.
        mov     x19, #0            // Intialize the loop control
        adr     x20, n             // Store n
        ldr     x20, [x20]

        // Read the numbers 

        adr     x0, prompt2        // Pass the prompt in x0
        bl      printf             // Call printf
        
test1:                             // Top of loop

        cmp     x19, x20           // Compare x19 and x0
        beq     done1              // Jump out of loop if equal
        
        adr     x0, infmt          // Pass the format in x0
        adr     x1, a              // Load the address of a into x1
        mov     x2, x19            // Get the index
        lsl     x2, x2, #3         // Multiply by 8
        add     x1, x1, x2         // Add the offset
        bl      scanf              // Call scanf
        
        add     x19, x19, #1       // Increment
        
        b       test1              // Jump to the top of the loop

done1:   

        // Print the numbers
        
        mov     x19, x20           // Initialize loop control
        sub     x19, x19, #1    

test2:                             // Top of loop

        cmp     x19, #0            // Compare x5 and 0
        blt     done2              // Jump out of loop if equal
        
        adr     x0, outfmt         // Pass the output format in x0
        adr     x1, a              // Load the address of a into x1
        ldr     x1, [x1,x19,lsl #3]   // Load the array element into x1
        bl      printf             // Call printf
        
        sub     x19, x19, #1       // Decrement
        b       test2              // Jump to the top of the loop

done2:   
        
        mov     x0, #0             // Return 0 in x0
        ldp     fp, lr, [sp], 16   // Pop the frame pointer and link register
        ret                        // Return from main

        .data                      // Start of data segment
        .align  3                  // Align on an even address

n:      .quad   0                  // Upper bound
a:      .fill   100, 8             // The array
        
prompt1: .string "how many? "              // Prompt string
prompt2: .string "enter the numbers: "     // Prompt string
infmt:   .string "%ld"                     // Input format
outfmt:  .string "%ld\n"                   // Output format
