Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

My response below has a problem compiling on line 209 (marked below in the provi

ID: 3581101 • Letter: M

Question

My response below has a problem compiling on line 209 (marked below in the provided code)

The purpose of this assignment is to explore methods to represent, access, and process arrays in Pentium Assembler. Briefly, you are going to define an array, initialize it with random values, and determine the sum, average, minimum, and maximum of the values in the array. For this assignment, you should use a new program skeleton called utilities.asm which is available on the software course web page.

Declare a symbol called N with a value of 10 to indicate the table size; declare a table called T of sizeNwhere each entry in T is 32 bits.

In addition to dump, utilities.asm also contains a function called rand8 which returns a random number in eax in the range [0..255]. Write a function called init that uses rand8 to initialize T to random values. Do not pass any arguments to init; init can refer to N and T directly. This function should not permanently modify any registers.*

Write a function that calculates the sum of the contents of T. Pass the address of T to the function in eax; pass N in ebx. Return the sum in eax. Do not modify any other registers.*

Write a function that calculates the minimum and maximum of the contents of T. Pass (the address of) T and (the value of) N by pushing them on the stack. Return the min in eax and the max in ebx. Do not modify any other registers.*

Extra credit. Write a function that calculates the average (using integer arithmetic) of the contents of T. Pass arguments by passing the address of a parameter block in eax. The parameter block should contain the address of T, the value of N, followed by space for the average. Do not modify any registers.*

Call dump (one last time) with the values of sum in eax, min in ebx, max in ecx, and avg in edx. (An easy way to do this is to define sum, etc. as variables and save the values as they are calculated.)

Demonstrate that your program works for 10 values. Make sure that your program can be easily changed to accommodate other values (such as 100000) for N.

Email a copy of your .asm file(s), as well as a file containing the output messages from your program(s).

MY FIle SO FAR (error message on line 209 I have no idea why):

;======================================================================
   TITLE   Program Utilities
;======================================================================
; File:       utilities.asm
;
; Date:       12/23/2004
; Description:
; This file contains a simple console program and includes the following
; functions:
; call dump     ;show the contents of registers
; call rand8   ;return a random number in eax in the range [0..255]
;   call resetTime   ;sets elapsed time timer back to zero
;   call reportTime   ;reports elapsed time in milliseconds
; Build:
; See build.bat for a command line oriented way to assemble and link
; this program. Simply type the following to create an executable:
; masm32inml /c /coff /Cp /nologo /Zd /Zi /Fl /Fm /FR /DDebug utilities.asm
; masm32inlink /nologo /map /debug /subsystem:console utilities.obj
; or
; build utilities
;======================================================================
; (this should not require any changes)
   .nolist           ;turn off listing
   .686           ;instructions for Pentium Pro (or better)
   .model   flat, stdcall   ;no crazy segments!
   option   casemap:none   ;case sensitive
;----------------------------------------------------------------------
; (insert needed external definitions here)
   include       masm32includewindows.inc
   include       masm32includemasm32.inc
   include       masm32includekernel32.inc
   include       masm32macrosmacros.asm

   includelib   masm32libmasm32.lib
   includelib   masm32libuser32.lib
   includelib   masm32libkernel32.lib
;----------------------------------------------------------------------
   .list       ;turn on listing
   .data       ;insert variables below
prompt   equ   ""   ;prompt string
;----------------------------------------------------------------------
   align   4
   .code       ;insert executable instructions below
main   PROC       ;program execution begins here
   mov   eax, 1   ;set regs values
   mov   ebx, 2
   mov   ecx, 3
   mov   edx, 4
   mov   esi, 5
   mov   edi, 6
  
  
  
   call   dump   ;show contents of regs
   mov   eax, input(prompt)   ;prompt the user
   exit       ;end of program
main   ENDP
;----------------------------------------------------------------------
;insert additional procedures/functions here

   .data
szTemp   byte   16 dup (?)   ;buffer for messages
szPrime   byte   "%08lx", 0   ;message format string

   .code
;32-bit windows calling conventions:
;   EBX, ESI, and EDI are preserved.
;   EAX, ECX, and EDX can be freely modified.

CR   =   13   ;carriage return
LF   =   10   ;linefeed

;this macro outputs a newline (cr,lf)
newline   MACRO
   print   SADD(CR,LF)
   ENDM
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
show   MACRO   caption, value
;note:   'value' must not be in eax, ecx, or edx (because they may be
;   modified by the first call).
   print   SADD(caption)
   mov   eax, value
   invoke   wsprintf, offset szTemp, offset szPrime, eax
   print   offset szTemp
   ENDM
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;(some of the) eflags bits:
;   ID-bit 21, OF-bit 11, SF-bit 7, ZF-bit 6, AF-bit 4, CF-bit 0
CF   equ   1b   ;carry flag bit
ZF   equ   1000000b   ;zero flag bit
SF   equ   10000000b   ;sign flag bit
OF   equ   100000000000b   ;overflow flag bit

;this function dumps the contents of the registers to the console.
;all of the caller's registers are preserved.
dump   PROC


   pushfd   ;save eflags
   pushad   ;save registers (order is: eax, ecx, edx, ebx,
       ; esp, ebp, esi, and edi)
   newline               ;end line
   ;output registers
   show   " eax:", [esp+28]   ;output eax
   show   " ebx:", [esp+16]   ;output ebx
   show   " ecx:", [esp+24]   ;output ecx
   show   " edx:", [esp+20]   ;output edx
   newline               ;end line
   show   " esp:", [esp+12]   ;output esp
   show   " ebp:", [esp+8]   ;output ebp
   show   " esi:", [esp+4]   ;output esi
   show   " edi:", [esp]       ;output edi
   show   " eip:", [esp+36]   ;output addr of next instruction
   newline               ;end line
   show   " Table:", [T]       ;output edi
   newline               ;end line
   ;output flags
   show   " eflags:", [esp+32]   ;output eflags
   mov   ebx, [esp+32]       ;fetch contents of saved eflags
   ;CF flag
   test   ebx, CF           ;carry set?
   jz   cf0           ;jump if 0
   print   SADD(" CF:1")       ;flag is on
   jmp   @f           ;skip over else part
cf0:
   print   SADD(" CF:0")       ;flag is off
@@:
   ;ZF flag
   test   ebx, ZF           ;zero set?
   jz   zf0           ;jump if 0
   print   SADD(" ZF:1")       ;flag is on
   jmp   @f           ;skip over else part
zf0:
   print   SADD(" ZF:0")       ;flag is off
@@:
   ;SF flag
   test   ebx, SF           ;sign set?
   jz   sf0           ;jump if 0
   print   SADD(" SF:1")       ;flag is on
   jmp   @f           ;skip over else part
sf0:
   print   SADD(" SF:0")       ;flag is off
@@:
   ;OF flag
   test   ebx, OF           ;overflow set?
   jz   of0           ;jump if 0
   print   SADD(" OF:1")       ;flag is on
   jmp   @f           ;skip over else part
of0:
   print   SADD(" OF:0")       ;flag is off
@@:
   newline               ;end line
   newline               ;end line
   ;project: add code to show contents of stack here
   popad               ;restore pushed registers
   popfd               ;restore eflags
   ret               ;return to caller
dump   ENDP
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   .data
seed   dword   11       ;random number generator seed (can't be 0)
;part1      
N equ 10 ;declare symbol N with value 10
T dword N dup(?) ;declare table T of size N =10
Min dword 0
Max dword 0

   .code
rand   PROC
   push   ecx       ;save modified registers
   push   edx
   ;Park Miller random number algorithm.
   ;Written by Jaymeson Trudgen (NaN)
   ;Optimized by Rickey Bowers Jr. (bitRAKE)
   ;
   ;this code is not commented because the original author did not
   ;comment it (not a good idea).
   ;
   mov   eax, seed
   xor   edx, edx
   mov   ecx, 127773
   div   ecx
   mov   ecx, eax
   mov   eax, 16807
   mul   edx
   mov   edx, ecx
   mov   ecx, eax
   mov   eax, 2836
   mul   edx
   sub   ecx, eax
   xor   edx, edx
   mov   eax, ecx
   mov   seed, ecx

   pop   edx       ;restore modified registers
   pop   ecx
   ret           ;return to caller
rand   ENDP

;GLOBAL rand8 ;declare rand8 as global
rand8   PROC
   call   rand       ;eax will contain a 32-bit random number
   and   eax, 0ffh   ;to yield a value in [0..255]
   ret           ;return to caller
rand8   ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;part2

;;; BELOW IS LINE 209 / where the problem is

init PROC
push eax ;save reg used
push ebx ;save reg used
push ecx ;save reg used

mov ebx, offset T ;get starting address of table
mov ecx, N ;get number of entries
lp:
cmp ecx, 0 ;all done?
jle lpDone ;jump if finished
call rand8 ;generate a random number
mov [ebx], eax ;save the random number in the table
add ebx, 4 ;point to the next table entry
dec ecx ;update the counter
jmp lp ;do the next one
lpDone:
pop ecx ;restore reg used
pop ebx ;restore reg used
pop eax ;restore reg used
ret ;return to caller
init ENDP

;part3
SumT PROC ;sums up the content of T, we may use a loop here, research more on that
push eax ;save reg used
push ebx ;save reg used
push ecx
  
   mov eax, offset T ;eax points to the first table entry
   mov ebx, [eax] ;ebx contains the first table entry
   mov ecx, N
lp1:
   ;add eax, 4 ;eax now points to next table entry
   CMP ecx, 0
   jge done
   add ebx, [eax] ;sum the second entry
   add ebx, 4 ;point to the next table entry
dec ecx
   mov eax, ebx
   jmp lp1
done:
pop ecx ;restore reg used
pop ebx ;restore reg used
pop eax ;restore reg used
ret ;return to caller
;call dump
SumT ENDP

;part4
Min PROC ;cal min max by pushing into stack
push eax ;save reg used
push ebx ;save reg used
push ecx
  
mov eax, offset T
   mov ebx, [eax] ;ebx contains the first table entry
   mov Min, ebx
   mov ecx, N
lp1:

CMP ecx, 0
jge done1
   add ebx, [eax] ;sum the second entry
   CMP ebx, Min
   jge donemin
   add ebx, 4 ;point to the next table entry
dec ecx
   mov ebx, Min

jmp lp1
donemin:
done1:
pop eax ;restore reg used
pop ebx ;restore reg used
pop ecx ;restore reg used
ret ;return to caller

Min ENDP

;part4
Max PROC ;cal min max by pushing into stack
push eax ;save reg used
push ebx ;save reg used
push ecx
   push edx
  
mov eax, offset T
   mov ebx, [eax] ;ebx contains the first table entry
   mov Max, ebx
   mov ecx, N
lpm:

CMP ecx, 0
jle donem
   add ebx, [eax] ;sum the next entry
   CMP ebx, Max
   jle donemax
   add ebx, 4 ;point to the next table entry
dec ecx
   mov ecx, Min
jmp lpm

donemax:
donem:
pop eax ;restore reg used
pop ebx ;restore reg used
pop ecx ;restore reg used
pop edx ;restore reg used
ret ;return to caller

Max ENDP

;part5
Avg PROC
   push eax ;save reg used
push ebx ;save reg used
push ecx
   push edx
  
   mov eax, offset T ;eax points to the first table entry
   mov ecx, N ;ebx contains the first table entry
   mov ebx, [eax] ;ebx contains the first table entry
lp2:
   cmp ecx, 0
;add eax, 4 ;eax now points to next table entry
;CMP ebx, N
   jge done3

   add ebx, [eax] ;sum the second entry
   add ebx, 4 ;point to the next table entry
dec ecx
mov eax, ebx
   mov edx, 0
jmp lp2
done3:
idiv ecx ;divide by N
   mov edx, eax
pop ecx ;restore reg used
pop ebx ;restore reg used
pop eax ;restore reg used
ret ;return to caller

Avg ENDP

   .data
startTicks   dword   0
   .code
resetTime   PROC
   pushad           ;save registers
   call   GetTickCount   ;get starting time
   mov   startTicks, eax   ;save start time
   popad           ;restore pushed registers
   ret           ;return to caller
resetTime   ENDP

   .data
timeMessage       byte   "elapsed time: %lu milliseconds", CR, LF, 0
timeMessageBuffer   byte   256 dup (0)
   .code
reportTime   PROC
   pushad           ;save registers
   call   GetTickCount   ;get ending time
   sub   eax, startTicks   ;calculate elapsed time
   invoke   wsprintf, offset timeMessageBuffer, offset timeMessage, eax
               ;create message
   print   offset timeMessageBuffer   ;output message

   popad           ;restore pushed registers
   ret           ;return to caller
reportTime   ENDP

   END   main
;======================================================================

Explanation / Answer

Answer:

Some points to note:

1. It is required to know what exactly error is.

2. Which assembler you are using because different assemblers may have different set of instructions and syntax.

3. Are you receiving error on line 209 only or there are more errors.

Some suggestions:

1. Check the syntax of defining a procedure as per the syntax of assembler being used.

2. Check whether type information of procedure or arguments, if any, are to be defined.

3. Look at 2-3 lines above 209 and below to check that all statements are ok.

4. Check you are not using an indentifier in duplicate manner.

Hope this helps you.