Given a list of numbers, looking at the extreme values (minimum and maximum) sometimes does not give us a full picture. Because those extreme values might be outliers. It might be more helpful to see multiple values at both ends, and calculate their average. In this assignment, you will write an assembly program to get the average of highest three elements in an array, and also the average of lowest three elements in the same array. You should complete this task in multiple steps. (1) Create a divide subroutine that divides first argument (dividend) by the second (divisor). The subroutine will return the integer quotient of division, discarding the remainder. To perform the division, you should do repeated subtraction until the dividend gets smaller than the divisor. For example, dividing 23 by 5 will be done as 23 – 5 = 18, then 18 – 5 = 13, then 13 – 5 = 8, then 8 – 5 = 3 which is less than 5, so we stop the subtraction. The quotient w
Given a list of numbers, looking at the extreme values (minimum and maximum) sometimes does not give us a full picture. Because those extreme values might be outliers. It might be more helpful to see multiple values at both ends, and calculate their average. In this assignment, you will write an assembly
You should complete this task in multiple steps.
(1) Create a divide subroutine that divides first argument (dividend) by the second (divisor). The subroutine will return the integer quotient of division, discarding the remainder.
To perform the division, you should do repeated subtraction until the dividend gets smaller than the divisor. For example, dividing 23 by 5 will be done as 23 – 5 = 18, then 18 – 5 = 13, then 13 – 5 = 8, then 8 – 5 = 3 which is less than 5, so we stop the subtraction. The quotient would be 4 (number of iterations).
You can NOT use the built in div instruction. Assume that we are working with unsigned numbers only. Furthermore, do not worry about invalid arguments (say, dividend smaller than divisor).
(2) Create a list_avg subroutine which takes in two parameters – an integer array (starting address) and its size. This subroutine will add all the numbers in the array, then divide the sum by array size to get the average. Average value is to be returned to caller via stack. Division should be performed by calling the divide subroutine.
(3) Finally, write the main program which will have an array marks and its size available as global variables.
To find the lowest and highest numbers in the array, the program will call the bubblesort subroutine (already provided to you).
Then, it will call the list_avg subroutine on first three elements of the sorted array. Use the same marks array as the first argument and 3 as the second argument of list_avg.
Next, the program will call list_avg for last three elements of the sorted array. You will need to get a pointer to 3rd-last element of marks, which will become the first argument of call to list_avg.
The main program should put the final results in [topAvg] and [bottomAvg] variables.
Note than the program should be generic, it should work correctly on other arrays of different size and values.
Skeleton Code:
[org 0x0100]
jmp start
; place final outputs in these variables
topAvg: dw 0
bottomAvg: dw 0
; the data array and its size
; change these two to ensure your program works correctly all the time
marks: dw 25, 26, 13, 47, 36, 32, 5, 40, 18, 11, 22, 25, 33, 28, 29, 16, 20, 23, 26, 20, 42, 31, 32, 29, 11
size: dw 25
;------------------------------------------------------------------
; bubblesort subroutine (Example 5.6 from BH)
; Required parameters (on stack): array start address, array size
; Returns: nothing
;------------------------------------------------------------------
bubblesort: push bp ; save old value of bp
mov bp, sp ; make bp our reference point
sub sp, 2 ; make two byte space on stack
push ax ; save old values of registers
push bx
push cx
push si
mov bx, [bp+6] ; load start of array in bx
mov cx, [bp+4] ; load count of elements in cx
dec cx ; last element not compared
shl cx, 1 ; turn into byte count
mainloop: mov si, 0 ; initialize array index to zero
mov word [bp-2], 0 ; reset swap flag to no swaps
innerloop: mov ax, [bx+si] ; load number in ax
cmp ax, [bx+si+2] ; compare with next number
jbe noswap ; no swap if already in order
xchg ax, [bx+si+2] ; exchange ax with second number
mov [bx+si], ax ; store second number in first
mov word [bp-2], 1 ; flag that a swap has been done
noswap: add si, 2 ; advance si to next index
cmp si, cx ; are we at last index
jne innerloop ; if not compare next two
cmp word [bp-2], 1 ; check if a swap has been done
je mainloop ; if yes make another pass
pop si ; restore old value of registers
pop cx
pop bx
pop ax
mov sp, bp ; remove space created on stack
pop bp ; restore old value of bp
ret 4 ; go back and remove two params
;------------------------------------------------------------------
; list_avg subroutine
; Required parameters (on stack): array start address, array size
; Returns (again, on stack): the average value
;------------------------------------------------------------------
list_avg: ;
;
; complete me
;
;
;------------------------------------------------------------------
; divide subroutine
; Required parameters (on stack): dividend, divisor
; Returns (on stack): the integer quotient
;------------------------------------------------------------------
divide: ;
;
; complete me
;
;
;------------------------------------------------------------------
; Main program
; Sorts the marks array using bubblesort subroutine, then
; calls list_avg subroutine on a sublist of first 3 elements
; and then on a sublist of last 3 elements
;------------------------------------------------------------------
start: ;
;
; complete me
;
;
finish: mov ax, 0x4c00
int 21h
Step by step
Solved in 3 steps