//---------------------------------------------------------------- // gpacalc.s // // This procedure shows a way of generating the string of // ascii characters which expresses a grade-point average // to the nearest hundredth. // // programmer: ALLAN CRUSE // written on: 15 OCT 2003 //---------------------------------------------------------------- .section .data .extern credits:int # total number of units taken .extern qpoints:int # total quality-points earned .extern gpabuff:char # buffer for the digit-string .section .text gpacalc: # compute (100 * qpoints)/credits to the nearest integer movl $100, %eax # setup the multiplicand in EAX mull qpoints # multiply it by quality-points divl credits # then divide it by the credits # rounding rule: if ( 2*remainder >= divisor ) ++quoient; addl %edx, %edx # now double the remainder-value cmpl credits, %edx # examine: 2*remainder - divisor cmc # reverse CF (the 'borrow' flag) adcl $0, %eax # use add-with-carry for roundup # convert the resulting quotient in EAX (as adjusted) to # a 3-digit string of decimal numerals, with a null-byte # appended (for printf), and with a decimal-point before # the leading digit. Here we generate these ascii-codes # in backward order, for convenience in coding the loop. movl $4, %edi # setup the maximum array-index movb $0, gpabuff(%edi) # and store a null-byte movl $3, %ecx # now ECX with count of digits movl $10, %ebx # setup EBX with decimal-radix nxdgt: xorl %edx, %edx # extend numerator for division divl %ebx # divide by the decimal radix addb $'0', %dl # convert remainder to numeral decl %edi # then back up the array-index movb %dl, gpabuff(%edi) # and store the numeral loop nxdgt # generate any remaining digits movb $'.', %dl # setup decimal-point character xchgb %dl, gpabuff(%edi) # swap w/ leading digit decl %edi # back up the array-index again movb %dl, gpabuff(%edi) # then store that digit ret # return control to the caller .globl gpacalc # so linker can find the symbol