Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- TITLE lab3 (lab3.asm)
- ; William Keller (#996964933) wjkeller@ucdavis.edu
- INCLUDE Irvine32.inc
- .data
- lab_grades BYTE 6 DUP(?)
- hw_grades BYTE 6 DUP(?)
- exam_grades BYTE 3 DUP(?)
- lab_intro BYTE "Enter the six lab grades: ",0
- lab_prefix_s BYTE "Lab",0
- lab_post_s BYTE ": ",0
- hw_intro BYTE "Enter the six Hw grades: ",0
- hw_prefix_s BYTE "Hw",0
- hw_post_s BYTE ": ",0
- exam_intro BYTE "Enter the three exam grades: ",0
- exam_prefix_s BYTE "Exam",0
- exam_post_s BYTE ": ",0
- total_s BYTE "Total Grade = ",0
- letter_s BYTE "Letter Grade = ",0
- .code
- main PROC
- call lab_in
- call hw_in
- call exam_in
- mov esi, OFFSET lab_grades ; Pass lab_grades to proc.
- call calc_dropped_total ; EAX now has lab total, with lower grade
- ; dropped.
- mov edx, 5
- mul edx ; EAX = EAX*5
- ; I couldn't find a way to eliminate
- ; the div later, so I figured I may
- ; as well use mul as well.
- mov ebx, eax ; EBX = EAX*5
- mov esi, OFFSET hw_grades ; Get ready to sum homeworks
- call calc_dropped_total ; EAX now has homeworks
- mov edx, 2 ; Yes, it's probably slower than adding
- mul edx ; it twice, but I want to be consistantA
- add ebx, eax ; EBX = LT * 5 + HT * 2
- mov esi, OFFSET exam_grades ; Now we have to do the exams; no
- ; dropping required, so we'll do it
- ; here.
- movzx eax, BYTE PTR [esi] ; EAX = E1
- mov edx, 15
- mul edx ; EAX = E1 * 20
- add ebx, eax ; EBX = LT*5+HT*2+E1*15
- inc esi ; Next one!
- movzx eax, BYTE PTR [esi] ; EAX = E2
- mov edx, 20
- mul edx ; EAX = E2 * 20
- add ebx, eax ; EBX=LT*5+HT*2+E1*15+E2*20
- inc esi ; Last one!
- movzx eax, BYTE PTR [esi] ; EAX = EF
- mov edx, 30
- mul edx ; EAX = EF * 30
- add ebx, eax ; EBX=LT*5+HT*2+E1*15+E2*20+EF*30
- mov eax, ebx
- mov dl, 100
- div dl ; Divide the whole thing by 100.
- ; AL has our total, the remainder is in
- ; AH. I'm not going check AH to round
- ; right because the example program
- ; doesn't.
- movzx eax, al ; EAX now has our grade. We blank out
- ; the upper bits with movzx because
- ; WriteInt takes all of EAX.
- ; Now EAX is our total!
- mov edx, OFFSET total_s
- call WriteString
- call WriteInt
- call Crlf ; A newline between them.
- call lookup_letter ; Swap the grade in AL for an ASCII
- ; value of the grade.
- mov edx, OFFSET letter_s
- call WriteString
- call WriteChar ; Letter grade in Al.
- exit ; Finallt done!
- main ENDP
- lookup_letter PROC
- ; Takes a grade in EAX and returns an ASCII value in al. We don't have
- ; to ZX it because WriteChar just reads AL.
- cmp al, 85 ; Our value is 100 or less, so it fits into AL.
- jg ltr_a
- cmp al, 75
- jg ltr_b
- cmp al, 65
- jg ltr_c
- cmp al, 59
- jg ltr_d
- ; If we're here, the student failed. :(
- mov al, 'F'
- ret ; Return now al is set.
- ltr_a: mov al, 'A'
- ret ; Return now al is set.
- ltr_b: mov al, 'B'
- ret ; Return now al is set.
- ltr_c: mov al, 'C'
- ret ; Return now al is set.
- ltr_d: mov al, 'D'
- ret ; Return now al is set.
- lookup_letter ENDP
- calc_dropped_total PROC ; This takes ESI (ptr to data) and
- ; leaves EAX (total with drop).
- ; WARNING! This trashes everything but ebx and edx
- ; We have to add up the top scores while dropping the lowest.
- ; I'll use an extra register and store the lowest while summing
- ; then subtract it out afterwards.
- push ebx ; Store B and D.
- push edx
- ; Takes ESI.
- mov bl, [esi] ; Take the first grade and
- ; put it in bl; we'll use B and D to compare scores.
- ; I'll leave the lowest in D and compare the current (B)
- ; against it.
- movzx ax, bl ; The l registers are going to top out! Need more space
- ; for our running total, so we'll upgrade to x.
- inc esi ; Next grade.
- mov ecx,5 ; Five more to go.
- add_l: movzx dx, BYTE PTR [esi] ; dl has new grade, eax is total
- ; bx is first value
- add ax, dx ; add to running total
- cmp dl, bl ; We don't have to ZX bl to bx because we can still
- ; compare to the low half of bx with bl
- jg skip ; new grade is bigger, toss it!
- mov bl, dl ; But if new grade is smaller, save it in bl!
- skip: inc esi ; Get ready to test the next value
- loop add_l ; And do it again.
- ; At this point, the total is in AX, and the lowest value is in BL.
- ; To subtract it, we have to ZX it to blank out the upper bits just in
- ; case.
- movzx bx, bl
- sub ax, bx
- movzx eax, ax ; WriteInt writes ALL of EAX, so blank out the rest
- ; of it.
- pop edx ; Restore D and B.
- pop ebx
- ret
- calc_dropped_total ENDP
- lab_in PROC ; Read in Lab grades
- ; We're gonna need a lot of registers
- push eax
- push esi
- push ecx
- push edi
- push edx
- mov edx, OFFSET lab_intro
- call WriteString
- call crlf
- mov esi, 0 ; Track number of lab we're on. (Zero indexed)
- mov edi, OFFSET lab_grades ; Array to store our values
- mov ecx, 6 ; 6 grades to get
- read_l: mov edx, OFFSET lab_prefix_s ; Start of prompt line "Lab"
- call WriteString ; Write it.
- mov eax, esi ; Move number of lab we're on to eax
- add al, 49 ; dec(48) == ascii('0'), dec(49) == ascii('1'), etc.
- ; Zero indexed, so add 1!
- call WriteChar ; Write lab number, no newline!
- mov edx, OFFSET lab_post_s ; Get ready to write colon and space
- call WriteString ; Write them!
- call Readint ; Read grade into al
- mov [edi], al ; Store it in our array
- inc edi ; Next byte please!
- inc esi ; Next number for prompt too!
- loop read_l ; Read next score
- ; restore registers just in case
- pop edx
- pop edi
- pop ecx
- pop esi
- pop eax
- ret
- lab_in ENDP
- hw_in PROC ; Read in homework grades
- ; We're gonna need a lot of registers
- push eax
- push esi
- push ecx
- push edi
- push edx
- mov edx, OFFSET hw_intro
- call WriteString
- call crlf
- mov esi, 0 ; Track number of lab we're on. (Zero indexed)
- mov edi, OFFSET hw_grades ; Array to store our values
- mov ecx, 6 ; 6 grades to get
- read_w: mov edx, OFFSET hw_prefix_s ; Start of prompt line "Hw"
- call WriteString ; Write it.
- mov eax, esi ; Move number of lab we're on to eax
- add al, 49 ; dec(48) == ascii('0'), dec(49) == ascii('1'), etc.
- ; Zero indexed, so add 1!
- call WriteChar ; Write lab number, no newline!
- mov edx, OFFSET hw_post_s ; Get ready to write colon and space
- call WriteString ; Write them!
- call Readint ; Read grade into al
- mov [edi], al ; Store it in our array
- inc edi ; Next byte please!
- inc esi ; Next number for prompt too!
- loop read_w ; Read next score
- ; restore registers just in case
- pop edx
- pop edi
- pop ecx
- pop esi
- pop eax
- ret
- hw_in ENDP
- exam_in PROC ; Read in exam grades
- ; We're gonna need a lot of registers
- push eax
- push esi
- push ecx
- push edi
- push edx
- mov edx, OFFSET exam_intro
- call WriteString
- call crlf
- mov esi, 0 ; Track number of exam we're on. (Zero indexed)
- mov edi, OFFSET exam_grades ; Array to store our values
- mov ecx, 3 ; 3 grades to get
- read_e: mov edx, OFFSET exam_prefix_s ; Start of prompt line "Exam"
- call WriteString ; Write it.
- mov eax, esi ; Move number of lab we're on to eax
- add al, 49 ; dec(48) == ascii('0'), dec(49) == ascii('1'), etc.
- ; Zero indexed, so add 1!
- call WriteChar ; Write lab number, no newline!
- mov edx, OFFSET exam_post_s ; Get ready to write colon and space
- call WriteString ; Write them!
- call Readint ; Read grade into al
- mov [edi], al ; Store it in our array
- inc edi ; Next byte please!
- inc esi ; Next number for prompt too!
- loop read_e ; Read next score
- ; restore registers just in case
- pop edx
- pop edi
- pop ecx
- pop esi
- pop eax
- ret
- exam_in ENDP
- END main
Add Comment
Please, Sign In to add comment