News:

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

examples needed

Started by nrdev, May 28, 2009, 10:19:54 PM

Previous topic - Next topic

dedndave

yes - i see the libraries - and the inc's
but i see no docs - no source code

i do see masm32\m32lib\nrand.asm
you might look at that

Jimg

Quote from: nrdev on May 30, 2009, 11:00:43 AM
Jimg have posted the right thing, but that code can't generate truly random numbers. I'am a bit confused I find randlib, that maybe can help me on this. But I doesn't understand what should be a DWORD type. Is it a number or char or what, how can I use that evry function in masm is different and all of the have this?
What do you mean by this?  You don't want the sequence to always start with the same number, or you don't want a repeatable sequence?  There are no "truly" random number generators created in code, it takes an uncontrollable physical process, like white noise, radioactive decay, etc.  Perhaps the best you can do is use the builtin timer, and do something in between each character that requires windows to do something, some nasty api, garbage collection, access the internet, time the users keystrokes, something that never runs exactly the same amount of time.  Then feed this into the seed and get a random number.

dedndave

i wrote one using the timer (not a great one - lol)
what makes it appear random is that the timer is counting at a very fast rate
the event of the function grabbing a value from it in code (a fairly good pseudo-random event) makes it a good generator

i wrote one for you before - here is a better one.....

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

        OPTION  PROLOGUE:NONE
        OPTION  EPILOGUE:NONE

Randm   PROC

;Random ASCII character generator
;generates numbers 0-9 and letters a-z (lower case)

;Call With: Nothing

;  Returns: eax = al = pseudo-random ASCII character

        INVOKE  Sleep,0
        sub     esp,8
        INVOKE  QueryPerformanceCounter,esp
        pop     eax
        xor     eax,[esp]
        add     esp,4
        xor     edx,edx
        mov     ecx,36
        div     ecx
        xchg    eax,edx
        add     eax,30h
        cmp     eax,39h
        jbe     Randm0

        add     eax,27h

Randm0: ret

Randm   ENDP

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef

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


that sucker will spit out random stuff all day
to use it......

        call    Randm    ;get random char in AL

nrdev

dedndave, how can I see the result of your code, I want it to be shown in the MessageBox.

dedndave

well - each time you call the "Randm" function, it returns a random character

to test it, make a string that is some specified length (let's say 10 characters long)

        mov     edi,offset RandomString
        mov     ecx,10

RTest0: push    edi
        push    ecx
        call    Randm
        pop     ecx
        pop     edi
        cld
        stosb
        loop    RTest0

after the loop executes, the "RandomString" will have 10 garbage characters

Jimg

Dave-

Since your proc has no parameters or locals, there is no reason to use option prologue:none.

In fact, there is good reason not to screw with option prologue unless absolutely necessary, I may already have one established.

Is there a "save the previous option prologue so I can restore it later" command?


nrdev

I have put it in my code like this

random_chars:

           .if letters + 1
               szText NSN,"Serial Number Creator"

               mov     edi,offset RandomString
               mov     ecx,10
               
               RTest0: push    edi
               push    ecx
               call    Randm
               pop     ecx
               pop     edi
               cld
               stosb
               
               loop    RTest0
               ret
           .endif

           invoke MessageBox,hWin,ADDR RandomString,ADDR NSN,MB_OK
           ret



but it returns error: "invalid operand for OFFSET"

dedndave

thanks Jim - i just wanted to turn off stack frames - i am a n00b to 32-bit world - lol

nrdev - i wrote a little program to test the generator
it runs in console mode - press any key when you have seen enough random chars



[attachment deleted by admin]

dedndave

nrdev - the invalid operand is the string name - you have to define the data buffer

add this to the data area.......

.data
RandomString db 12 dup(0)

PBrennick

nrdev,

ESI and EDI are special case registers mostly used for string manipulatuion. Because of this you MUST use LEA, so:

mov     edi,offset RandomString

should be;

lea     edi, RandomString

If you were using EBX;

mov     ebx,offset RandomString

would work.

This is always true.
Paul
The GeneSys Project is available from:
The Repository or My crappy website

PBrennick

Also, this is the random number generator I used in Sudoku,


Random              PROTO :DWORD
TimerProc           PROTO :DWORD, :DWORD, :DWORD, :DWORD


.data
system_time SYSTEMTIME  <>              ; Used to seed the random number generator


.data?
rseed       dd      ?


; The following is in various portions of WndProc

; This is in
    .if uMsg == WM_CREATE

      invoke  GetLocalTime, addr system_time    ; Ensures the first Game appears to be random
      xor     eax, eax                  ; Need a byte value so clear the rest
      mov     ax, system_time.wMilliseconds     ; Get the currnt time (millseconds)
      mov     rseed, eax                ; Store it as the initial seed
      invoke  SetTimer, hWnd, 200, 50, offset TimerProc ; Randomizes the rest of the Games

; This goes wherever you want
      invoke  Random, 4999                ; Randomly (sort of) select a Puzzle

; Now

Random  proc    range:DWORD
;--------------------------------------
    mov     eax, rseed                  ; rseed varies according to the timer
    mov     ecx, 23                     ; Multiplier used to inflate that value
    mul     ecx                         ; The rest of this stuff just mucks with the result
    add     eax, 7                      ; in such a way that the ssed is
    and     eax, 0FFFFFFFFh             ; returned with a different value
    ror     eax, 1                      ; to prevent sequential Puzzles
    xor     eax, rseed                  ; being chosen by this process
    mov     rseed, eax                  ; because TimerProc just bumps the seed by one
    mov     ecx, range                  ; Largest value allowed
    xor     edx, edx                    ; Prepare for the result of the division
    div     ecx                         ; Get the Integer portion of the result
    mov     eax, edx                    ; Result is returned in EAX
    ret
;--------------------------------------
Random  endp

TimerProc proc hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
;--------------------------------------
    inc     rseed                       ; Pretty basic, I know, but it is good enough
    ret
;--------------------------------------
TimerProc endp


for your purposes, you need to set the value used by

      invoke  Random, 4999


4999 in this casebecause there are 5000 puzzles in each of four levels, to be the maximum value you wish to obtain.

The stuff in TimerProc is pretty basic but works great, you could add further coding here if necessary. rseed is scoped and will just rollover and over, etc. so, for your purposes, you could invoke TimerProc at many portions of your program. No matter what you do, there is always a pattern, unavoildable. You can eliminate this effect to some degree by reading the Mouse position and use that value to further obfuscate rseed. Just an idea. Mous motions are truly random.

Also, you can add WM_TIMER to WndProc and invoke TimerProc from in there to get some continual alterations to the seed.

Paul
The GeneSys Project is available from:
The Repository or My crappy website

dedndave

hmmmmmm
i use mov esi,offset label and mov edi,offset label all the time

PBrennick

I have used it successfully also. But sometimes for reasons I cannot say, it does NOT work, so I stopped using it in that manner.

Paul
The GeneSys Project is available from:
The Repository or My crappy website

dedndave

wow - that is new to me - if you run across a case like that, let me know
inquiring minds need to know !! - lol

donkey

Quote from: dedndave on May 30, 2009, 06:32:20 PM
hmmmmmm
i use mov esi,offset label and mov edi,offset label all the time


Since offset label is calculated by the assembler and passed as an absolute (with rebasing by the PE loader) there is no other explanation than an assembler bug for any failure of this instruction. The ability to pass a label address to EDI and ESI is inherent in the processor, they are the source and destination registers for string and table functions so they are expected and designed to receive offsets.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable