News:

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

trying to understand randomize and unsigned??

Started by bcddd214, April 22, 2011, 11:20:58 PM

Previous topic - Next topic

dedndave

i still don't know what you are going for
certainly, i would try to use the same code for both functions
there are a few ways to do that, depending on the situation

for example, i might write a RandLoop function that has 3 parameters
then, write another one that has only 2
inside that function, i would fill in the 3rd paramter and use the other two from the invoke

there is an important thing to understand, here
that is, the assembler generates exit code whenever you add a RET instruction
among other things, it uses a special form of RET that pops the parameters off the stack
so, a function that has 3 parameters will use a RET 12, and a function that has 2 parameters will use a RET 8
that means you can't "mix and match", or "nest" dissimilar functions

dedndave

here is a little explanation of the assembler generated code...
http://www.masm32.com/board/index.php?topic=15307.msg124847#msg124847

and a little more involved one that shows how to write your own stack frame
http://www.masm32.com/board/index.php?topic=14381.msg114921#msg114921

bcddd214

I GOT IT!

working code!
:)

        TITLE   Random

        INCLUDE Irvine32.inc

RandLoop PROTO  :DWORD,:DWORD
RandLoop2 PROTO  :DWORD,:DWORD,:DWORD

;#########################################################

COUNT   = 10
COUNT2   = 2
;#########################################################

        .DATA

commaStr BYTE ", ",0
str1 BYTE "Total=  ",0

;#########################################################

        .CODE
RandLoop PROC   dwMinVal:DWORD,dwMaxVal:DWORD
        LOCAL   dwRange:DWORD
        mov     eax,dwMaxVal   ;you are loading the registers to prepare for the value here?
        sub     eax,dwMinVal   ;you are loading the registers to prepare for the value here?
        mov     dwRange,eax      ;I am confuse because I am not used to seeing more than one thing in a register at a time?
        mov     edx,OFFSET commaStr
        mov     ecx,COUNT
;      call DumpRegs

RLoop0: mov     eax,dwRange       ; generate rand int
        call    RandomRange
        add     eax,dwMinVal
        call    WriteInt          ; display the integer
        call    WriteString
        loop    RLoop0
      call    Crlf
      call    Crlf
        ret
RandLoop ENDP

;second loop begins here to count to random colums down
RandLoop2 PROC   dwMinVal2:DWORD,dwMaxVal2:DWORD,COLUMN:DWORD
;this procedure show X columns of random value betwen dwMinVal and dwMaxVal
;this procedure add one colum to show the sum of values
        LOCAL   dwRange2:DWORD
LOCAL VALUE_FINAL:DWORD

mov VALUE_FINAL,0 ;we initialize this variable with zero
;cmp COLUMN,0 ;zero columns?
;mov COUNT2,0 ;set count2 to zero
JE DO_NOTHING ;so do nothing
        mov     eax,dwMaxVal2
        sub     eax,dwMinVal2
        mov     dwRange2,eax
        mov     edx,OFFSET commaStr
;        mov     ecx,COLUMN
      mov     ecx,COUNT2
RLoop1:
mov     eax,dwRange2
        call    RandomRange
        add     eax,dwMinVal2
      add [VALUE_FINAL],eax ;first moment the value_final is zero, second moment is ????????
        call    WriteInt
        call    WriteString
;        call DumpRegs
      loop    RLoop1
      
      mov edx, offset str1 ;we show the "total= "
        call    WriteString
        mov eax,VALUE_FINAL ;and after we show the sum of the numbers
        call WriteInt
        call    Crlf ;an enter in the end of column

DO_NOTHING:
        ret
RandLoop2 ENDP


main    PROC
        call    Clrscr     
        call    Randomize      ;initialize random generator
        INVOKE  RandLoop,0,8   ;The use of INVOKE here is incremental from RandLoop? Grabs this one first,
        INVOKE  RandLoop,25,92   ;Then this one second
        INVOKE  RandLoop,-5,6   ;and this one last. No more INVOKEs so the loop terminates?
      INVOKE  RandLoop2,1,6,0
      INVOKE  RandLoop2,1,6,0
      INVOKE  RandLoop2,1,6,0
      INVOKE  RandLoop2,1,6,0
      INVOKE  RandLoop2,1,6,0
      INVOKE  RandLoop2,1,6,0
      INVOKE  RandLoop2,1,6,0
      INVOKE  RandLoop2,1,6,0
      INVOKE  RandLoop2,1,6,0
      INVOKE  RandLoop2,1,6,0
        call    Crlf
        exit

main    ENDP

;#########################################################

        END     main

mineiro

Hello bcddd214, when you are learning assembly you need follow some rules. This is not absolutely true, but when learning, this works.
1 - every "call" have a "ret". So if you call some procedure, inside that procedure have a ret.
2 - comment your code so much, put in the header of 'proc' a comment saying what that procedure does, what registers are modified, what that procedure returns, and what the procedures need to work.
3 - Local variables inside a proc are only seen inside that proc. Global variables are seen by all the program, they are stored in .data section. And equates (=) are constants.
4 - Don't think that the values in the registers are preserved, because you can do a call to some procedure and that procedure can modify some registers/flags.

So when you see a "call Crlf" remember that inside that procedure, have a ret to return to your code again.
When you see a "invoke Crlf" remember that inside that procedure have a ret to return to your code again.
You called(invoke) RandLoop2 10 times alright? So, you can rewrite it using loop:

main    PROC
        call    Clrscr     
        call    Randomize      ;initialize random generator
        INVOKE  RandLoop,0,8   ;The use of INVOKE here is incremental from RandLoop? Grabs this one first,
;no, invoke is a call, nothing related with loop
        INVOKE  RandLoop,25,92   ;Then this one second
;yes, another call
        INVOKE  RandLoop,-5,6   ;and this one last. No more INVOKEs so the loop terminates?
;no, there is no loop here, below have a loop
        mov ecx,10     ;we will count it 10 times
again:        ;again is a label to a loop, see below to understand
        push ecx         ;here, we save the ecx register, because I don't know if RandLoop2 modify this register, and yes, RandLoop2 modify that register
;so if in ecx we have 10, and do a call to RandLoop2, we don't know what have in ecx after that call.
      INVOKE  RandLoop2,1,6,0
        pop  ecx         ;now, we get back that saved ecx register
        dec  ecx          ; we subtract 1 from ecx, you can use "sub ecx,1"
        cmp ecx,0        ;ecx is 0? if yes, so we have done it, if no, so do it again
        jz done           
        jmp again
done:         ;done is a label to get out of loop
        call    Crlf
        exit

main    ENDP

"call" is not equal of loop. Call is a jmp to another portion of your code, but after that code is done, so it "ret" to your code again.
"loop" is a jmp too, but it decrements the ecx register.
"call" do like a: "save(push) the address of where to return(the nex code after call), and after jmp to that procedure"
"ret" do like a: "restore(pop) the address saved, and after jmp to that address"
"loop" do like a: "jmp to some address and decrement ecx".
"invoke" is a bit more complex, but in essence is a "call".
You can use only "invoke" if you like, but to processor, invoke does not exist, only "call".Invoke is to make call more easy,
The same code as above, but here using loop.

main    PROC
        call    Clrscr     
        call    Randomize      ;initialize random generator
        INVOKE  RandLoop,0,8   ;The use of INVOKE here is incremental from RandLoop? Grabs this one first,
        INVOKE  RandLoop,25,92   ;Then this one second
        INVOKE  RandLoop,-5,6   ;and this one last. No more INVOKEs so the loop terminates?
        mov ecx,10     ;we will count it 10 times
again:        ;again is a label to a loop, see below to understand
        push ecx         ;here, we save the ecx register, because I don't know if RandLoop2 modify this register
      INVOKE  RandLoop2,1,6,0
        pop  ecx         ;now, we get back that saved ecx register
        loop again        ;the loop decrement ecx, after, compare it to see if it is zero, if yes, have done, if no, jmp to again
        call    Crlf
        exit
main    ENDP

If you see the RandLoop , it has a constant, to say, COUNT   = 10. And if you change the COUNT to 1, and in another portion of your code , to say, RandLoop2, make a loop to call it 10 times.

KeepingRealBusy

Something nagged at me so I went back and found my Kip library. RandomRange returns a random number between 0 and n-1, so you will never get the last value. You have to increase the n value by 1 just before you call RandomRange to get the full range of possibilities. Picky, Picky, Picky.

Dave.


jj2007

Quote from: KeepingRealBusy on April 24, 2011, 10:55:11 PMRandomRange returns a random number between 0 and n-1, so you will never get the last value.

Which is standard practice for most languages I know, including MasmBasic and GfaBasic.

dedndave


KeepingRealBusy

Quote from: jj2007 on April 25, 2011, 06:41:07 AM
Quote from: KeepingRealBusy on April 24, 2011, 10:55:11 PMRandomRange returns a random number between 0 and n-1, so you will never get the last value.

Which is standard practice for most languages I know, including MasmBasic and GfaBasic.


My point exactly. If you want to get random digits between 0 and 9 you must call RandomRange with a value of 9+1 or you will never see a 9 digit.

bcddd214

?
I changed my invoke value from
INVOKE  RandLoop2,1,6,0
to
INVOKE  RandLoop2,1,10,0

and was about to pull up 9 a couple of times.

dedndave

better to fix it here
that way, the INVOKES work as desired   :U
        mov     eax,dwMaxVal
        sub     eax,dwMinVal
        inc     eax                         ;add this line
        mov     dwRange,eax

bcddd214


dedndave

nahhhh
they tell me how slow my code is everytime i make an attachment   :lol