/******************************************************* * File: ArrayStructSearch.m * Date: Oct. 31, 2021 * Author: Dr. Spiegel * Computer: Acad * Execute: ArrayStructSearch * 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) # 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 define(keyAdrsReg,%r12) # Couldn't use %r11; it kept getting clobbered .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 20 bytes to hold a name during the search 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 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 $280, %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"