/******************************************************* * File: DateEx.m * Dir: cis235/suns/ch05 * Date: April 15, 2003 * Author: DSS * Computer: KUNET suns * Assembler: as under the gcc compiler * Compile: gcc * Execute: DateEx * Purpose: Read up to 10 Dates (month/day); 4 bytes per value, 8 per record * could use 1 byte, but no format spec to read number in 1 byte * -sort Dates and print * -use boolean array to facilitate sort *******************************************************/ ! Use macros to make things clear!!! ! Allocation of Frame variables define(uAdrs,-96) define(oAdrs,-176) define(sAdrs,-178) ! Macros for accessing array elements and fields of records define(eltOffset,%l0) define(dateAdrs,%g3) ! Data registers define(items,%g2) define(indx,%g5) define(sortReg,%l1) define(boolReg,%l2) define(holdReg,%l5) define(idxMax,%l3) define(idx,%l4) define(maxMonth,%i1) define(maxDay,%i2) define(day,%i3) define(month,%i4) define(temp,%l6) define(storeIdx,%l7) .data .align 8 ! Global format strings hello: .asciz "Enter up to 10 Dates: \n" dateIn: .asciz "%d %d" dateOut:.asciz "%d/%d\n" outMsg: .asciz "\n************* The Dates, in order: *************\n" .align 8 .text .global main main: ! Allocate the frame save %sp,(-108-162) & -8, %sp ! Input up to 10 Date records set hello,%o0 call printf !********************************************** ! for(i = 0;!done && i < 10; i++) { ! scanf(dateIn, &uAdrs[i]); ! } mov 0, idx ! i = 0; ! Initialize counter in printf's delay inLoop: set dateIn,%o0 sll idx,3,eltOffset ! i * 8 gives offset in bytes: 8 bytes/record add %fp,uAdrs,temp add temp,eltOffset,dateAdrs !record base address mov dateAdrs,%o1 ! month call scanf add dateAdrs,4,%o2 ! day : delay slot ! ^D ?? cmp %o0,2 bne inputDone nop inc idx ! 10 items? subcc idx,10,%g0 ! compare bne inLoop nop inputDone: mov idx,items ! Hold onto # elements ! Sort time!! mov idx,storeIdx ! storeIdx holds index in destination list clr sortReg sortLoop: dec storeIdx andcc storeIdx,storeIdx,%g0 ! set Z flag if storeIdx==0 bz copyLast sub items,1,idx ! rightmost unsorted index in oAdrs ! move index to rightmost unsorted index in uAdrs mov 1,boolReg ! use rightmost 10 bits of boolReg mov 10,temp sub temp,items,temp sll boolReg,temp,boolReg ! boolReg's 1 is parallel to last used elt rIdxLoop: ! test if bit in sortReg corresp. to 1 in boolReg is 0; if not, move left andcc boolReg,sortReg,%g0 ! Corresp. bits in bool & sort both 0? bz got1stIdx ! Stop when it is so nop sll boolReg,1,boolReg ! shift 1 left if last sortReg bit was 1 dec idx ba rIdxLoop nop ! Now, time to find maximums got1stIdx: sll idx,3,eltOffset add uAdrs,eltOffset,temp ld [%fp+temp],maxMonth add temp,4,temp ld [%fp+temp],maxDay mov idx,idxMax mov boolReg,holdReg ! keep track of bit for max value traverse: cmp idx,0 ! idx==0 means we store present max now bz noMore ! nothing more to look at, otherwise... sll boolReg,1,boolReg ! shift 1 left if last sortReg bit was 1 dec idx ! and decrement idx andncc boolReg,sortReg,%g0 ! looking for 1 in boolreg and 0 in sort bz traverse ! if not, go left again nop ! load max unsorted value from unsorted array sll idx,3,eltOffset add uAdrs,eltOffset,dateAdrs ld [%fp+dateAdrs],month add dateAdrs,4,dateAdrs ld [%fp+dateAdrs],day ! Check if this date is after max; lots of possibilities cmp maxMonth,month ! compare months be checkDays ! if equal, need to check days nop bg noMax ! don't have a new max nop ba newMax ! maxMonth