/******************************************************* * File: ArrayStructMalloc.m * Date: Nov. 25, 2021 * Author: Dr. Spiegel * Computer: Acad * Execute: ArrayStructMalloc * 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 * A basic search for a name follows * * This program will define an array (size 10) of struct stored * in the stack and use a loop to read in *up to* ten values * and then print them out. * *******************************************************/ define(name,0) # 23 char string dynamically allocated define(age,8) # 32-bit int define(level,12) # char representing class '1'=fr '2'=so, etc. define(student,16) # 16 bytes/student (why, when only 13 used?) define(List,160) # 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 define(keyAdrsReg,%r12) .global main .extern strcmp .extern strlen main: push %rbp # keep stack aligned # Make room for 10 records on the stack subq $List, %rsp # must also remain divisible by 16 subq $16, %rsp # We will need 8 bytes to hold a name during the search movq $0, count # Count # elts movq %rsp, eltAdrs # Base address is the stack pointer loop: # Prompt for name leaq getName(%rip), %rdi # load format string to proper register call printf # print it # Dynamically allocate space for the name movq $20, %rdi # We will allocate 20 bytes for the name call malloc movq %rax, (eltAdrs) # Store the address in the name part of the record # Read the name movq (eltAdrs), %rdi # Place malloc'd memory adrs as parameter 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 addq $student, eltAdrs # eltAdrs += sizeOf(student); for input next record 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 search: leaq getSrchKey(%rip), %rdi # load format string to proper register call printf # print it # Read the search key (a name) movq %rsp, %rdi # End of array addq $List, %rdi movq %rdi, keyAdrsReg # Save in a 'safe' register call gets # Read the name # Check is the string is empty movq keyAdrsReg, %rdi call strlen cmp $0, %rax je done # Perform the search - Compare the names of each elt until found (or not) movq %rsp, eltAdrs # No functions, so %rsp is okay (instead of param) movq $-1,index # Initially -1 so we can inc at start of loop srchLoop: inc index cmp count,index # Have we run out of places to look? je notFound movq keyAdrsReg, %rdi # End of array is address of search key movq (eltAdrs), %rsi # Next name addq $student, eltAdrs # Update eltAdrs to next record call strcmp cmp $0,%rax # If 0, they matched jne srchLoop movq $srchFnd, %rdi movq index, %rsi jmp prtRes notFound: movq $srchNot, %rdi prtRes: call printf jmp search done: addq $List, %rsp # Deallocate the array addq $16, %rsp # Deallocate spave for search key 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" getSrchKey: .asciz "Enter Name to Search (Hit Enter to Exit): " srchFnd:.asciz "Name found in Index %d \n" srchNot:.asciz "Name not found \n"