News:

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

Help with global variables and division

Started by sydetys, October 12, 2008, 02:06:04 PM

Previous topic - Next topic

sydetys

Hi!

I have tried all, and worked nicely on, but now I have a wall in front of me..again, so I decided to risk and ask.

My code:
( console version, in .data? section there is two variables:  "nro     dd   ?" and  "nro2    dd   ?")

I have marked problem area with <---- below.
       

.code

start:

call number_gen
call div

number_gen proc

cls

    mov nro2, sval(input("give number : "))

invoke GetTickCount
invoke nseed, eax

invoke nrandom, 5000

    mov nro, eax

    print str$(nro)
    print chr$(10)

    print str$(nro2)

ret
number_gen endp

div proc

    LOCAL osam:DWORD
    LOCAL jakoj:DWORD
   
    mov eax, nro2
    mov cx, nro <-------------------------------------------PROBLEM LINE------
    div cx

    mov osam, eax
    mov jakoj, edx
   
    print chr$(10)
    print str$(osam)
    print chr$(10)
    print str$(jakoj)

ret
div endp


end start


My goal: is 1st to get number from user and then divide it with random number BUT when I try to divide my variable "nro" is too big, and if I use ECX instead of CX, calculation won´t work (=64bit?). I have tried [] but no help there.

Am I on the right track that I have to mody variable "nro" in .data? and repalce "dd" with something else, or is there more?

thanx

Added code tags. If it's not clear how this is done, click the modify button and look at what was added.

MichaelW

For mov, as for most instructions that take 2 operands, the operands need to be the same size. Why won't the calculation work with a DIV ECX? One problem I see is that you are not controlling the upper 8/16/32 bits of the dividend. Your code is effectively doing a DX:AX/CX, with an unknown value in DX. For a DIV ECX, which would effectively be EDX:EAX/ECX, if you intended for the dividend to be only the value in EAX, you would need to zero EDX before you performed the division.
eschew obfuscation

qWord

hi sydetys,

you should also know that sval() returns a signed value, so you have to use idiv:

mov eax,nro2
cdq                ;Sign-extend EAX into EDX:EAX.
mov ecx,nro
idiv ecx
; eax = quotient, edx = remainder

BTW: do not use reserved words (div) as names for procs
FPU in a trice: SmplMath
It's that simple!

sydetys

#3
Quote from: qWord on October 12, 2008, 04:30:05 PM
BTW: do not use reserved words (div) as names for procs

Ooops, I just copy pasted everything and turned lines in finnish to english, so "div proc" is really different, I made that conversion only ´cos it helps you to understand my code...

If I turn div CX to ECX I get only 0..I try that XORing mentioneed, lets see.....

Yes, If I use ECX and not CX, value inside register is zero

so I would have as result from this program:

random number
input number
0
inputnumber

I tried "cdq" too, no help..

I use 64bit Vista would that cause some trouble?
I tried all what qWord suggests  it won´t work,  ECX is still zero

sydetys

I isolated division segment adn YES it should work with ECX!

So this means my variable "nro" is ZEROED,

good revelation means step foreward, anyone know WHY variable "nro" is zeroed?

should I use SVAL?

thanx

MichaelW

The only way I can see that nrandom could consistently return zero would be if the seed were zeroed. If the seed were not zeroed, then the probability of nrandom with a base of 5000 returning zero should close to 1 in 5000.
eschew obfuscation

sydetys

#6
Quote from: MichaelW on October 12, 2008, 07:29:29 PM
The only way I can see that nrandom could consistently return zero would be if the seed were zeroed. If the seed were not zeroed, then the probability of nrandom with a base of 5000 returning zero should close to 1 in 5000.

I have made this thing lttle by little, and if I remove "div proc" and print nro and nro2 after random number has given then results would be right when printed on-screen, so nrandom itself doesn´t zero anything..unless it is zeroed when calling "div proc" but I have hard time accepting that...nro2 remains..so why wouldn´t nro..a bug?

UPDATE:

I took liberty to modify my code so that user gives both numbers, divisor and divident as variable nro and nro2, respectively, and code works fine, JUST fine.

that means result from nrandom even if saved in variable is reset to zero if jumping out of subprogram to another...I wonder why..

MichaelW

Try posting your complete source code, instead of only the .code section.
eschew obfuscation

raymond

If your random number generator is functioning as expected (and you seem to comfirm it), you would expect the returned number to be about 2500 on average.

If your input number is anywhere smaller than the random number, use some paper and pencil and do the division by hand and check what kind of answer you should expect......

Your code is probably working fine now and should return "0" as the answer of the division most of the time. :clap: Remember that integer division will return simply the truncated integer quotient.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

sydetys

#9
right, I have learned A LOT while making this program, I am going to scrap whole random generator thingy and set a new course for this program, I try to make something usefull, like basic calculator.

If Michael is still at least partally interested here is WHOLE code:

NRANDOM bit has been changed already, nro and nro2 has swapped their places, "<-----" marks where nrandom WAS.
I have to see that div and cdq things later, I consentrate to unsigned numbers for now.

BTW if you have comments about this...go ahead.



.686p                                   ; create 32 bit code
.mmx
.xmm
.model flat, stdcall                    ; 32 bit memory model
option casemap :none                    ; case sensitive

    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\masm32.inc
    include \masm32\macros\macros.asm
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
   
 
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
   


.data
       
          s1      db "*******************************", 10,9,9,9
        w1      db "*                                                 *", 10,9,9,9
        w2      db "**                                               **", 10,9,9,9
        med     db "***       LASKULUUPPI                  ***", 10,9,9,9
        w3      db "****                                           ****", 10,9,9,9
        w4      db "*****                                         *****", 10,9,9,9
         s2      db "*******************************", 10,9,9,9
        e1      db "                                                    ", 10,9,9,9
        e2      db "                                                     ", 10,9,9,9,0

.data?

        nro     dd  ?
        nro2    dd  ?

.code

start:

call number
call jako

SetTextColor proc fore:DWORD,back:DWORD

    LOCAL hStdOut:DWORD

    invoke GetStdHandle,STD_OUTPUT_HANDLE
    mov   hStdOut,eax
    mov   eax,back
    shl   eax,4
    or    eax,fore
    invoke SetConsoleTextAttribute,hStdOut,eax
    ret

SetTextColor endp

number proc

cls

invoke SetTextColor, 10, 0

invoke StdOut, addr e2     
invoke StdOut, addr s1

    mov nro, sval(input("Anna jaettava luku : "))
    mov nro2, sval(input("Anna jakaja : "))<---------------------------NRANDOM WAS HERE BEFORE----


    print str$(nro)
    print chr$(10)

    print str$(nro2)

ret
number endp

jako proc

    LOCAL osam:DWORD
    LOCAL jakoj:DWORD
   
    xor edx, edx
    mov eax, nro
    ;cdq                 ;Sign-extend EAX into EDX:EAX.
    mov ecx, nro2
    div ecx            ; eax = quotient, edx = remainder
             

    mov osam, eax
    mov jakoj, edx
   
    print chr$(10)
    print str$(osam)
    print chr$(10)
    print str$(jakoj)

ret
jako endp


end start



2 x BTW: I know FPU calculation would be better, but basic assembler is hard enough still for me...and this way learns more basics
   

MichaelW

The only problem I can see is that you are not ending the program after the call to jako returns, so execution is continuing into SetTextColor. You would normally end the program at this point by calling the ExitProcess function.
eschew obfuscation

sydetys

#11
You mean  before "end start" I should invoke ExitProcess?
I removed that because this seemed exit just fine....maybe it was error from my part...

BTW I hope nobody gets mad but I don´t want to start NEW thread because my new problem is part of this same program.
I mean I have no problem because this seems to work but I need some explanation.

I want user to press L to end program and J to start all over again at the end, that means I have..and I want... to change those letters into ASCII numbers, I made this code which is STILL at the separate ASM file and beginning
is copy from previous code, data is thus:


.DATA
   
.DATA?

    abc            dd  ?

.CODE

start:

merkin_anto:

xor eax, eax
mov eax, input ("Anna ASCII merkki: l , j : ")
mov abc, sval(eax)
print str$(abc)
print chr$(10)
exit
end start



What that result number from code above represents??

According masm help file, that is not ascii value. I get from this code: a = 49, b = 50,  y = 73, Y= 41 and number 9 = 9. I checked hex and "normal" numbers, doesn´t match with masm32 tables.

If I don´t use SVAL() I don´t get right result...few minutes back I got unsigned value without SVAL...if I remember right I used [eax] when moving to abc before printing....doesn´t suddenly work anymore...strange.

thanx for patience

PS HEEY! I found solution without SVAL(): directly after inptut has given + moved to eax  must: print str$([eax]). I get example: a = 655457, b= 655458
when eax has moved to variable abc, printing with [abc] won´t work anymore, so eax have to move as SVAL () into abc..cool



MichaelW

Quote from: sydetys on October 13, 2008, 10:14:53 PM
You mean  before "end start" I should invoke ExitProcess?
I removed that because this seemed exit just fine....maybe it was error from my part...

No, I mean immediately after the call jako statement. As the code currently is, when the jako procedure returns, execution continues in the SetTextColor procedure, and the program does not exit until after it reaches the ret instruction at the end of the procedure. In this particular case the code in the procedure does not cause any real problems, but in most cases allowing this sort of thing to happen will cause real problems.

The input macro returns the address of a string. While you could scan the string for a case-insensitive match for L or J, I would use the getkey macro (or call the MASM32 ret_key procedure, which is what the getkey macro does) to get a single character from the console and compare it to both possible cases for L and J.
eschew obfuscation