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

The instructions are below, please read thoroughly I\'m only have problems with

ID: 3897601 • Letter: T

Question

The instructions are below, please read thoroughly

I'm only have problems with filling the array appropriately, I believe there is a bug in getString macro or readVal procedure

Any help would be appreciated


Objectives: 1) Designing, implementing, and calling low-level I/O procedures

2) Implementing and using a macro Problem Definition:

• Implement and test your own ReadVal and WriteVal procedures for unsigned integers.

• Implement macros getString and displayString. The macros may use Irvine’s ReadString to get input from the user, and WriteString to display output.

getString should display a prompt, then get the user’s keyboard input into a memory location

displayString should print the string which is stored in a specified memory location.

readVal should invoke the getString macro to get the user’s string of digits. It should then convert the digit string to numeric, while validating the user’s input.

writeVal should convert a numeric value to a string of digits, and invoke the displayString macro to produce the output.

• Write a small test program that gets 10 valid integers from the user and stores the numeric values in an array. The program then displays the integers, their sum, and their average. Requirements:

1) User’s numeric input must be validated the hard way: Read the user's input as a string, and convert the string to numeric form. If the user enters non-digits or the number is too large for 32-bit registers, an error message should be displayed and the number should be discarded.

2) Conversion routines must appropriately use the lodsb and/or stosb operators.

3) All procedure parameters must be passed on the system stack.

4) Addresses of prompts, identifying strings, and other memory locations should be passed by address to the macros.

5) Used registers must be saved and restored by the called procedures and macros.

6) The stack must be “cleaned up” by the called procedure.

7) The usual requirements regarding documentation, readability, user-friendliness, etc., apply.


Notes: 1) For this assignment you are allowed to assume that the total sum of the numbers will fit inside a 32 bit register. 2) When displaying the average, you may round down to the nearest integer. For example if the sum of the 10 numbers is 3568 you may display the average as 356.

Explanation / Answer

INCLUDE Irvine32.inc

;------------------------------------------------------------------------------

; getString

; Displays a prompt to the user, then gets the user's keyboard input into a

; memory location.

;------------------------------------------------------------------------------

getString MACRO promptAddr, buffer, buffer_size

push edx

push ecx

mov edx, promptAddr ; display the supplied prompt

call WriteString

mov edx, buffer

mov ecx, buffer_size

call ReadString

pop ecx

pop edx

ENDM

;------------------------------------------------------------------------------

; displayString

; Displays the string stored in a specific memory location.

;------------------------------------------------------------------------------

displayString MACRO strAddress

push edx

mov edx, strAddress

call WriteString

pop edx

ENDM

.data

programTitle BYTE "ASSIGNMENT: Designing low-level "

BYTE "I/O procedures", 0

instructions BYTE "Please provide 10 unsigned decimal integers.", 13, 10

BYTE "Each number needs to be small enough to fit inside a "

BYTE "32 bit register.", 13, 10

BYTE "After you have finished inputting the raw numbers I "

BYTE "will display a list", 13, 10

BYTE "of the integers, their sum, and their average "

BYTE "value.", 0

numPrompt BYTE "Please enter an unsigned integer: ", 0

errorMsg BYTE "ERROR: You did not enter an unsigned number or your "

BYTE "number was too big.", 0

tryAgain BYTE "Please try again: ", 0

enteredMsg BYTE "You entered the following numbers:", 0

commaSpace BYTE ", ", 0

sumMsg BYTE "The sum of these numbers is: ", 0

avgMsg BYTE "The average is: ", 0

thanksMsg BYTE "Thanks for playing!", 0

array DWORD 10 DUP(?)

.code

main PROC

push OFFSET programTitle

push OFFSET instructions

call introduction

; getData controls the input loop

push OFFSET array

push LENGTHOF array

push OFFSET numPrompt

push OFFSET tryAgain

push OFFSET errorMsg

call getData

push OFFSET array

push LENGTHOF array

push OFFSET enteredMsg

push OFFSET commaSpace

call displayList

push OFFSET array

push LENGTHOF array

push OFFSET sumMsg

push OFFSET avgMsg

call displaySumAvg

push OFFSET thanksMsg

call displayEnd

exit

main ENDP

;------------------------------------------------------------------------------

; introduction

;------------------------------------------------------------------------------

introduction PROC USES edx

; set up stack frame

push ebp

mov ebp, esp

; display program title: programTitle = [ebp + 16]

mov edx, [ebp + 16]

displayString edx

call Crlf

call Crlf

; display program instructions: instructions = [ebp + 12]

mov edx, [ebp + 12]

displayString edx

call Crlf

call Crlf

pop ebp

ret 8

introduction ENDP

;------------------------------------------------------------------------------

; getData

; Gets user input from the keyboard to fill an array.

;------------------------------------------------------------------------------

getData PROC USES esi ecx eax

; set up stack frame

push ebp

mov ebp, esp

; fill array: array = [ebp + 36]

mov esi, [ebp + 36]

mov ecx, [ebp + 32]

fillArray:

mov eax, [ebp + 28] ; numPrompt = [ebp + 28]

push eax

push [ebp + 24] ; tryAgain = [ebp + 24]

push [ebp + 20] ; errorMsg = [ebp + 20]

call readVal

pop [esi] ; store converted number in array

add esi, 4

loop fillArray

pop ebp

ret 20

getData ENDP

;------------------------------------------------------------------------------

; readVal

; Reads user input from the keyboard

;------------------------------------------------------------------------------

readVal PROC USES eax ebx

LOCAL inputNum[15]:BYTE, valid:DWORD

; save esi and ecx and set up strings for getString

push esi

push ecx

mov eax, [ebp + 16] ; numPrompt = [ebp + 16]

lea ebx, inputNum

inputLoop:

getString eax, ebx, LENGTHOF inputNum

mov ebx, [ebp + 8] ; load errorMsg for validate

push ebx

lea eax, valid

push eax

lea eax, inputNum

push eax

push LENGTHOF inputNum

call validate

pop edx

mov [ebp + 16], edx ; store converted number in [ebp + 16]

mov eax, valid ; determine if input number is valid

cmp eax, 1

mov eax, [ebp + 12]

lea ebx, inputNum

jne inputLoop

pop ecx

pop esi

ret 8 ; do not clean up [ebp + 16], as it stores the number

readVal ENDP

;------------------------------------------------------------------------------

; validate

;------------------------------------------------------------------------------

validate PROC USES esi ecx eax edx

LOCAL tooLarge:DWORD

; set up source index and loop counter

mov esi, [ebp + 12]

mov ecx, [ebp + 8]

cld

; load in string byte by byte and verify if they are digits

loadStr:

lodsb

cmp al, 0

je nullChar

cmp al, 48

jl invalid

cmp al, 57

ja invalid

loop loadStr

; set valid to 0

invalid:

mov edx, [ebp + 20] ; errorMsg = [ebp + 20]

displayString edx

call Crlf

mov edx, [ebp + 16] ; set valid to false

mov eax, 0

mov [edx], eax

jmp endVal

; converts string to integer

; uses convertNum and tooLarge to check if number is too large

nullChar:

mov edx, [ebp + 8] ; check if anything was entered

cmp ecx, edx ; if ecx is the same as LENGTHOF array

je invalid ; null was entered

lea eax, tooLarge

mov edx, 0

mov [eax], edx

push [ebp + 12]

push [ebp + 8]

lea edx, tooLarge

push edx

call convertToNum

mov edx, tooLarge

cmp edx, 1

je invalid

mov edx, [ebp + 16]

mov eax, 1 ; set valid to true

mov [edx], eax

endVal:

pop edx ; pop whatever was returned from convertNum

mov [ebp + 20], edx ; store converted number in [ebp + 20]

ret 12 ; do not clean up [ebp + 20]

validate ENDP

;------------------------------------------------------------------------------

; convertToNum

;------------------------------------------------------------------------------

convertToNum PROC USES esi ecx eax ebx edx

LOCAL number:DWORD

; set up esi, ecx loop counter, number, eax, ebx, and edx

mov esi, [ebp + 16]

mov ecx, [ebp + 12]

lea eax, number

xor ebx, ebx

mov [eax], ebx

xor eax, eax

xor edx, eax ; also clears overflow and carry flags

cld

; load in string bytes one by one and add to number

loadDigits:

lodsb

cmp eax, 0

je endLoad

sub eax, 48

mov ebx, eax

mov eax, number

mov edx, 10

mul edx

jc numTooLarge ; check for carry after multiply

add eax, ebx

jc numTooLarge ; check for carry after adding

mov number, eax ; store temporary number from eax

mov eax, 0 ; reset eax

loop loadDigits

endLoad:

mov eax, number

mov [ebp + 16], eax ; move converted number to stack

jmp finish

; change tooLarge if number does not fit in 32-bit register

numTooLarge:

mov ebx, [ebp + 8] ; tooLarge = [ebp + 8]

mov eax, 1 ; set tooLarge to true

mov [ebx], eax

mov eax, 0

mov [ebp + 16], eax ; move placeholder 0 to stack

finish:

ret 8

convertToNum ENDP

;------------------------------------------------------------------------------

; displayList

; Uses register indirect addressing to display an array of numbers of a given

; size. Uses code from Lecture #20. Converts the integers to strings

; before displaying, then uses the displayString macro.

;------------------------------------------------------------------------------

displayList PROC USES esi ebx ecx edx

; set up stack frame

push ebp

mov ebp, esp

; print array title

call Crlf

mov edx, [ebp + 28]

displayString edx

call Crlf

mov esi, [ebp + 36]

mov ecx, [ebp + 32]

mov ebx, 1 ; counter for numbers in current row

printNum:

push [esi]

call WriteVal

add esi, 4

cmp ebx, [ebp + 32]

jge endList ; do not write commaSpace after last number

mov edx, [ebp + 24] ; commaSpace = [ebp + 24]

displayString edx

inc ebx

loop printNum

endList:

call Crlf

pop ebp

ret 16

displayList ENDP

;------------------------------------------------------------------------------

; displaySumAvg

; Displays the sum and average of an array of integers. Displays the sum and

; average as strings by calling on writeVal.

;------------------------------------------------------------------------------

displaySumAvg PROC USES esi edx ecx eax ebx

; set up stack frame

push ebp

mov ebp, esp

mov edx, [ebp + 32] ; sumMsg = [ebp + 32]

displayString edx

mov esi, [ebp + 40] ; array = [ebp + 40]

mov ecx, [ebp + 36] ; LENGTHOF array = [ebp + 36]

xor eax, eax ; also clears overflow and carry flags

; calculate sum

sumNumbers:

add eax, [esi]

add esi, 4

loop sumNumbers

; display sum

push eax

call writeVal

call Crlf

; calculate and display average

mov edx, [ebp + 28] ; avgMsg = [ebp + 28]

displayString edx

cdq

mov ebx, [ebp + 36] ; LENGTHOF array = [ebp + 36]

div ebx

push eax

call writeVal

call Crlf

pop ebp

ret 16

displaySumAvg ENDP

;------------------------------------------------------------------------------

; writeVal

; Writes an integer to the console as a string. Calls on convertChar to convert

; an integer to a string.

;------------------------------------------------------------------------------

writeVal PROC USES eax

LOCAL outputStr[11]:BYTE

lea eax, outputStr

push eax

push [ebp + 8]

call convertChar

lea eax, outputStr

displayString eax

ret 4

writeVal ENDP

;------------------------------------------------------------------------------

; convertChar

; Converts an integer to a string and saves it in outputStr (from writeVal).

;------------------------------------------------------------------------------

convertChar PROC USES eax ebx ecx

LOCAL tempChar:DWORD

; set up division of integer by 10

mov eax, [ebp + 8]

mov ebx, 10

mov ecx, 0

cld

; count the number of digits and push the digits in reverse order

divideTen:

cdq

div ebx

push edx ; remainder = last digit

inc ecx

cmp eax, 0

jne divideTen

mov edi, [ebp + 12] ; set up destination char array

storeChar:

pop tempChar

mov al, BYTE PTR tempChar

add al, 48

stosb

loop storeChar

mov al, 0

stosb

ret 8

convertChar ENDP

;------------------------------------------------------------------------------

; displayEnd

; Displays the program ending to the user.

;------------------------------------------------------------------------------

displayEnd PROC USES edx

; set up stack frame

push ebp

mov ebp, esp

call Crlf

mov edx, [ebp + 12]

displayString edx

call Crlf

pop ebp

ret 4

displayEnd ENDP

END main

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote