/******************************************************* * File: ArrayOfStruct.m * Date: Oct. 31, 2021 * Author: DSS * Computer: KUNET suns * Execute: ArrayOfStruct * Purpose: to demonstrate the use of arrays as allocated on the stack. * This example shows an array of struct * It illustrates how components of the arrays are referenced * Also, the nuances of alignment come into play * efficiently and demonstrates offsets via an index search * * This program will define an array (size 10) of struct stored * in the stack and use a for loop to read in *up to* ten values * and then print them out. * *******************************************************/ define(name,0) # 20 char string define(age,20) # 32-bit int define(level,24) # char representing class '1'=fr '2'=so, etc. define(student,28) # 28 bytes/student (why, when only 25 used?) define(List,288) # Space required for the array define(count,%r14) # Counter register define(index,%r15) define(eltAdrs,%r13) # Register used to keep track of where to store fields .global main main: push %rbp # keep stack aligned # Make room for 10 ints on the stack subq $List, %rsp # must also remain divisible by 16 movq $0, count # Count # elts loop: # Next record offset must be found movq %rsp, eltAdrs # Base address is the stack pointer movq $student, %rax mulq count # %rax now holds offset to this elt addq %rax, eltAdrs # Read into eltAdrs+offset # Prompt for name leaq getName(%rip), %rdi # load format string to proper register call printf # print it # Read the name # leaq fmt_in(%rip), %rdi # load format string movq eltAdrs, %rdi addq $name, %rdi # Offset to name call gets # Read the name # Did they enter ^D (eotext)? gets returns null on ^D cmp $0,%rax je print # If equal, time to print # Prompt for age leaq getAge(%rip), %rdi # load format string for age prompt call printf # print it # Read it leaq int_in(%rip), %rdi # load format string for int movq eltAdrs, %rsi addq $age, %rsi # Offset to name call scanf # Prompt for level leaq getClass(%rip), %rdi # load format string for age prompt call printf # print it # Read it leaq char_in(%rip), %rdi # load format string for int movq eltAdrs, %rsi addq $level, %rsi # Offset to level movq %rsi, %rdx # What's going on? Five arguments? movq %rdx, %rcx # How does it work? Why three chars? addq $2,%rcx call scanf # Check if 10 elements read inc count # Counter up # cmp $10,count # If equal, time to exit cmp $4,count # If equal, time to exit jz print jmp loop # If you get here, go get next value dec count # xor eltAdrs,eltAdrs print: # Print Header leaq header(%rip), %rdi # load format string for age prompt call printf # print it movq %rsp, eltAdrs # Base address is the stack pointer movq $0, index # #elts is in count, %r15 is now counting printLoop: leaq output(%rip),%rdi # Output format set to 1st argument movq eltAdrs,%rsi addq $name, %rsi # Offset to name movq eltAdrs,%rdx addq $age, %rdx # Address of age in %rdx movq (%rdx),%rdx # age is now in %rdx movq eltAdrs,%rcx addq $level, %rcx # Address of level in %rcx movq (%rcx),%rcx # level is now in %rcx call printf #inc eltAdrs to next elt addq $student,eltAdrs # Are we done? inc index # Inc counter cmp count,index # Equal to # elts? jl printLoop # No? Print next value done: addq $List, %rsp # Deallocate the array (not critical) pop %rbp ret .data getName: .asciz "Enter Name: " getAge: .asciz "Enter Age: " getClass: .asciz "Enter Class 1)Frosh 2)Soph 3)Jr 4)Sr >" int_in: .asciz "%d" char_in: .asciz "%c%c%c" output: .asciz "Name: %16s Age: %4d Class: %2c\n" header: .asciz "\nPeople Entered\n"