News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Masm project, don't know what im doing wrong

Started by president evil, March 11, 2011, 04:38:35 AM

Previous topic - Next topic

president evil

Problem Definition:
A system is required for statistics students to use for drill and practice in combinatorics. In particular, the
system will ask the student to calculate the number of combinations of r items taken from a set of n items
(i.e., nCr ). The system generates random problems with n in [3 .. 12] and r in [1 .. n]. The student enters
his/her answer, and the system reports the correct answer and an evaluation of the student's answer. The
system repeats until the student chooses to quit


1) The calculation must use the formula
r!(n r)!
n!
.The factorial calculation must be done recursively .
2) User's numeric input must be validated the hard way: Read the user's input as a string, convert the
string to numeric form. If the user enters non-digits, an error message should be displayed.
3) All parameters must be passed on the system stack.
4) Used registers must be saved and restored by the called procedure.
5) The stack must be "cleaned up" by the called procedure.
6) The program must be modularized into at least the following procedures:
a. main: mostly pushing parameters and calling procedures.
b. introduction: display title, programmer name, and instructions.
c. showProblem: generates the random numbers and displays the problem
showProblem accepts addresses of n and r.
d. getData: prompt / get the user's answer.
answer should be passed to getData by address (of course!).
e. combinations, factorial: do the calculations.
combinations accepts n and r by value and result by address.
combinations calls factorial (3 times) to calculate n!, r!, and (n-r)!.
combinations calculates
r!(n r)!
n!
, and stores the value in result.
f. showResults: display the student's answer, the calculated result, and a brief statement about the
student's performance
showResults accepts the values of n, r, answer, and result.
7) You should use a string display macro to display strings.
8) The usual requirements regarding documentation, readability, user-friendliness, etc., apply



right now it will do everything except give the correct answer

my code:


TITLE Program Assignment 5 (Program5.asm)

; Author:Karmandeep Bassi
; Course / Project ID:CS271 / Programming Assignment 5 Date:3/10/2011
; Description: Was not able to finish program, I got as far as trying to convert the users string input to an integer value.
; The program displays the title and program name and gives instructions for the combinations calculator. Next the problem is
; displayed along with two random numbers and the user is ask to input there answer. The program then reads the users input as
; a string and validates that it is a number and also makes sure the input is not greater then 3 digits.
;

INCLUDE Irvine32.inc

myWriteString MACRO buffer
push edx
mov edx, OFFSET buffer
call WriteString
pop edx

ENDM

MAX_SIZE=15

.data
inString BYTE MAX_SIZE DUP (?)
ans DWORD ?
strLen DWORD ?
hi DWORD ?
lo DWORD ?
nRandom DWORD ?
rRandom DWORD ?
int1 DWORD ?
count DWORD ?
min DWORD 9
max DWORD 201
nlo DWORD 3
nhi DWORD 12
rlo DWORD 1
rhi DWORD ?
limit DWORD 4

space3 BYTE " ",0 ; 3 blank spaces
myTitle BYTE "Programming Assignment 5, Combinations Calculator",0
myName BYTE "Programmed by Karmandeep Bassi",0
instr1 BYTE "I'll give you a combinations problem. You enter your answer, ",0
instr2 BYTE "and I'll let you know if you're right. ",0

problem1 BYTE "Problem: ",0
problem2 BYTE "Number of elements in the set: ",0
problem3 BYTE "Number of elements to choose from the set: ",0
userQues BYTE "How many ways can you choose? ",0
falseAns BYTE "Invalid input. Please enter a number that is between 0 and 999",0
bye BYTE "Thank you for using my Random Numbers program, goodbye",0
testRun BYTE "I made it here",0
.code
main PROC
call Randomize

call introduction

call showProblem


push OFFSET inString
push MAX_SIZE
call getData

call farwell
exit

main ENDP

; Procedure to introduce the program.
; receives: none
; returns: none
; preconditions: none
; registers changed: edx

introduction PROC

; Display instructions

myWriteString myTitle
call Crlf
myWriteString myName
call Crlf
call Crlf
myWriteString instr1
call Crlf
myWriteString instr2
call Crlf
call Crlf
ret

introduction ENDP

showProblem PROC

nRand:
mov eax, nhi
sub eax, nlo
inc eax
call RandomRange
add eax, nlo
mov nRandom, eax

rRand:
mov eax, nRandom
sub eax, rlo
inc eax
call RandomRange
add eax, rlo
mov rRandom, eax

displayProblem:

myWriteString problem1
call Crlf
myWriteString problem2
mov eax, nRandom
call WriteDec
call Crlf

myWriteString problem3
mov eax, rRandom
call WriteDec
Call Crlf

ret

showProblem ENDP

; Procedure to get value for int1 from user
; receives: none
; returns: user input value for int1
; preconditions: none
; registers changed: eax, edx, ebp, esp, ebx

getData PROC

push ebp
mov ebp,esp
mov edx,[ebp+12]
mov ecx, [ebp+8]


userInput:

myWriteString userQues
call ReadString
call Crlf
mov esi, edx
mov strLen, eax
cmp eax, 3
ja toLarge
;mov edx, 0
;mov ebx, 10
cld

validate:
lodsb
cmp al, 48
jb OutofRange
cmp al, 57
ja OutofRange
;movzx edi, al
;m;ov eax, edx
;mul ebx
;mov edx, eax
;sub edi, 48
;add edx, edi
;loop validate
;mov ans, edx
jmp endGetData

toLarge:
myWriteString falseAns
call Crlf
call Crlf
jmp again

OutOfRange:
myWriteString falseAns
call Crlf
call Crlf
jmp again

again:
myWriteString problem1
call Crlf
myWriteString problem2
mov eax, nRandom
call WriteDec
call Crlf

myWriteString problem3
mov eax, rRandom
call WriteDec
Call Crlf
jmp userInput



endGetData:
mov eax, ans
call WriteDec
pop ebp
ret 8


getData ENDP


farwell PROC

;display goodbye message

;call Crlf
mov edx,OFFSET bye
call WriteString
call Crlf
call Crlf

farwell ENDP

exit ; exit to operating system


; (insert additional procedures here)

END main


Added code tags

dedndave

Quoteright now it will do everything except give the correct answer
:lol

welcome to the forum
maybe tomorrow, i'll have a look at it

qWord

; r!(n r)!
include masm32rt.inc

fac proto x:DWORD

.code
main proc
LOCAL r:DWORD
LOCAL rI:QWORD
   
    ;invoke AllocConsole

    mov edx,a2ud(input("r: "))
    mov edx,DWORD ptr [edx]
    mov r,edx

    invoke fac,r
    mov DWORD ptr rI[0],eax
    mov DWORD ptr rI[4],edx
   
    print uqword$(rI),13,10
   
    inkey
    exit
   

main endp
fac proc x:DWORD
LOCAL q:QWORD

    .if x > 1
        mov edx,x
        invoke fac,ADDR [edx-1]
        push edx
        mov ecx,x
        mul ecx
        mov DWORD ptr q[0],eax
        mov DWORD ptr q[4],edx
        pop edx
        mov eax,x
        mul edx
        add eax,DWORD ptr q[4]
        mov edx,eax
        mov eax,DWORD ptr q[0]
    .else
        xor edx,edx
        mov eax,1
    .endif
    ret

fac endp
end main
FPU in a trice: SmplMath
It's that simple!

raymond

If you limit the value of "n" to 12, 12! does not exceed the 32-bit integer. And, if allowed, it would be much more efficient to build an array of the factorials up to 12! and later use those values for your calculations.

If such a table is not allowed, you could go up to 16 for a maximum value of "n" since, in the worse case, C(16,x) would never exceed 32-bit integers if you compute it efficiently.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

dedndave

you can also increase the range by factoring the (n-r)! term of the denominator out of the numerator prior to recursion
it's also considerably faster

combinations


permutations


notice that, for permutations, if n=7 and r=3, the calculation is simplified as:

= 2x3x4x5x6x7 / 2x3x4
= 5x6x7