Write an assembly language program which will call several procedures. The proce
ID: 664601 • Letter: W
Question
Write an assembly language program which will call several procedures. The procedures, their parameters, and their purposes are as follows (shown in C++ format):
void AVGS (int LIST[], int N, int &AVE, int &AVEP, int &AVEN)
LIST is a one dimensional array of signed integers and N is the number of elements in that array. Both of these are input parameters to the procedure. The procedure AVGS must calculate 1) the average of the N integers in LIST and return the result in AVE, 2) the average of the positive numbers (> 0) and return the result in AVEP, and 3) the average of the negative numbers (< 0) and return the result in AVEN.
int LARGE (int LIST[], int N)
LIST and N are as above. The function returns the value of the largest element in the array. Note that the integer result is to be returned in register EAX. Note that this is typical of value returning functions in C++.
In C++, passing the parameters would be done on the stack. However, since we haven’t covered how to do that, you are to use registers to pass them. It is up to you as to which registers you should use. Pay attention as to which parameters are passed by value and which by reference. Note that arrays are always passed by reference. Also, note that int refers to 32 bit values. Do not directly access the parameters via the .data section.
The main program will loop twice, performing the following tasks each time:
1) Read in a set of data
2) Call both of the above procedures
3) Display the data values and the results of the procedures (the average, the positive average, the negative average, and the largest value)
Use the following test data (there are two sets):
A) 4 -30 0 7 42 -20 18 400 -123 -6
B) 2 17 -5 0 20 15 -16 -3 -2 14
-1 12 1 -5 -100 15 22 -5 68 -13
Your program should run both data sets in one execution. DO NOT RUN THE PROGRAM TWICE!
Explanation / Answer
main:
; initializes the two numbers and the counter. Note that this assumes
; that the counter and num1 and num2 areas are contiguous!
;
mov ax,'00' ; initialize to all ASCII zeroes
mov di,counter ; including the counter
mov cx,digits+cntDigits/2 ; two bytes at a time
cld ; initialize from low to high memory
rep stosw ; write the data
inc ax ; make sure ASCII zero is in al
mov [num1 + digits - 1],al ; last digit is one
mov [num2 + digits - 1],al ;
mov [counter + cntDigits - 1],al
jmp .bottom ; done with initialization, so begin
.top
; add num1 to num2
mov di,num1+digits-1
mov si,num2+digits-1
mov cx,digits ;
call AddNumbers ; num2 += num1
mov bp,num2 ;
call PrintLine ;
dec dword [term] ; decrement loop counter
jz .done ;
; add num2 to num1
mov di,num2+digits-1
mov si,num1+digits-1
mov cx,digits ;
call AddNumbers ; num1 += num2
.bottom
mov bp,num1 ;
call PrintLine ;
dec dword [term] ; decrement loop counter
jnz .top ;
.done
call CRLF ; finish off with CRLF
mov ax,4c00h ; terminate
int 21h ;
;****************************************************************************
;
; PrintLine
; prints a single line of output containing one term of the
; Fibonacci sequence. The first few lines look like this:
;
; Fibonacci(1): 1
; Fibonacci(2): 1
; Fibonacci(3): 2
; Fibonacci(4): 3
;
; INPUT: ds:bp ==> number string, cx = max string length
; OUTPUT: CF set on error, AX = error code if carry set
; DESTROYED: ax, bx, cx, dx, di
;
;****************************************************************************
PrintLine:
mov dx,eol ; print combined CRLF and msg1
mov cx,msg1len+eollen ;
call PrintString ;
mov di,counter ; print counter
mov cx,cntDigits ;
call PrintNumericString
call IncrementCount ; also increment the counter
mov dx,msg2 ; print msg2
mov cx,msg2len ;
call PrintString ;
mov di,bp ; recall address of number
mov cx,digits ;
; deliberately fall through to PrintNumericString
;****************************************************************************
;
; PrintNumericString
; prints the numeric string at DS:DI, suppressing leading zeroes
; max length is CX
;
; INPUT: ds:di ==> number string, cx = max string length
; OUTPUT: CF set on error, AX = error code if carry set
; DESTROYED: ax, bx, cx, dx, di
;
;****************************************************************************
PrintNumericString:
; first scan for the first non-zero byte
mov al,'0' ; look for ASCII zero
cld ; scan from MSD to LSD
repe scasb ;
mov dx,di ; points to one byte after
dec dx ; back up one character
inc cx ;
; deliberately fall through to PrintString
;****************************************************************************
;
; PrintString
; prints the string at DS:DX with length CX to stdout
;
; INPUT: ds:dx ==> string, cx = string length
; OUTPUT: CF set on error, AX = error code if carry set
; DESTROYED: ax, bx
;
;****************************************************************************
PrintString:
mov bx, 1 ; write to stdout
mov ah, 040h ; write to file handle
int 21h ; ignore return value
ret ;
;****************************************************************************
;
; AddNumbers
; add number 2 at ds:si to number 1 at es:di of width cx
;
;
; INPUT: es:di ==> number1, ds:si ==> number2, cx= max width
; OUTPUT: CF set on overflow
; DESTROYED: ax, si, di
;
;****************************************************************************
AddNumbers:
std ; go from LSB to MSB
clc ;
pushf ; save carry flag
.top
mov ax,0f0fh ; convert from ASCII BCD to BCD
and al,[si] ; get next digit of number2 in al
and ah,[di] ; get next digit of number1 in ah
popf ; recall carry flag
adc al,ah ; add these digits
aaa ; convert to BCD
pushf ;
add al,'0' ; convert back to ASCII BCD digit
stosb ; save it and increment both counters
dec si ;
loop .top ; keep going until we've got them all
popf ; recall carry flag
ret ;
;****************************************************************************
;
; IncrementCount
; increments a multidigit term counter by one
;
; INPUT: none
; OUTPUT: CF set on overflow
; DESTROYED: ax, cx, di
;
;****************************************************************************
IncrementCount:
mov cx,cntDigits ;
mov di,counter+cntDigits-1
std ; go from LSB to MSB
stc ; this is our increment
pushf ; save carry flag
.top
mov ax,000fh ; convert from ASCII BCD to BCD
and al,[di] ; get next digit of counter in al
popf ; recall carry flag
adc al,ah ; add these digits
aaa ; convert to BCD
pushf ;
add al,'0' ; convert back to ASCII BCD digit
stosb ; save and increment counter
loop .top ;
popf ; recall carry flag
ret ;
;****************************************************************************
;
; CRLF
; prints carriage return, line feed pair to stdout
;
; INPUT: none
; OUTPUT: CF set on error, AX = error code if carry set
; DESTROYED: ax, bx, cx, dx
;
;****************************************************************************
CRLF: mov dx,eol ;
mov cx,eollen ;
jmp PrintString ;
;****************************************************************************
; static data
;****************************************************************************
eol db 13,10 ; DOS-style end of line
eollen equ $ - eol
msg1 db 'Fibonacci(' ;
msg1len equ $ - msg1
msg2 db '): ' ;
msg2len equ $ - msg2
;****************************************************************************
; initialized data
;****************************************************************************
term dd maxTerms ;
;****************************************************************************
; unallocated data
;
; A better way to do this would be to actually ask for a memory
; allocation and use that memory space, but this is a DOS COM file
; and so we are given the entire 64K of space. Technically, this
; could fail since we *might* be running on a machine which doesn't
; have 64K free. If you're running on such a memory poor machine,
; my advice would be to not run this program.
;
;****************************************************************************
; static data
counter: ;
num1 equ counter+cntDigits ;
num2 equ num1+digits ;
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.