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
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.