flat assembler
Message board for the users of flat assembler.

Index > Tutorials and Examples > [fasmg] Generate Random Data File:

Author
Thread Post new topic Reply to topic
bitRAKE



Joined: 21 Jul 2003
Posts: 4073
Location: vpcmpistri
bitRAKE 09 May 2021, 09:31
Code:
; simple program to output random data to file
;
; TODO: add seed file option
; TODO: make a 32-bit version

BLOCK_SIZE := 1 shl 16 ; increase this if you are more ambitious :P

format PE64 CONSOLE 5.1 ; XP
entry GoTime
include 'win64w.inc'

label Message:(Message_end - $)shr 1
TCHAR 10,9,"Random Data File Generator v0.1",10
TCHAR 9,"usage: prngdata {bytes} {file}",10,10
TCHAR 9,"{bytes} will except postfixes of K/k, M/m, or G/g.",10
TCHAR 9,"Multiplier of 2^10, 2^20 or 2^30 respectively.",10,10
TCHAR 9,"{file} cannot exist - will not overwrite.",10
Message_end:

include 'superkiss64.fasmg' ; random number generator


; RAX - wide-string pointer
wTo_u64: ; (modified for custom parsing)
        push rsi
        xchg rsi,rax
        xor eax,eax
        xor edx,edx
.read:
        imul rdx,rdx,10
        add rdx,rax

        lodsw
        test eax,eax
        jz .done
        sub eax,'0'
        jc .done ; error
        cmp eax,10
        jc .read
        cmp word [rsi],0
        jnz .error
        ; minimal overflow checking, could probably set more bits ;)
        mov rsi,$FFC0'0000'0000'0000
        iterate C, 'k','m','g'
                test rdx,rsi
                jnz .error
                or eax,$20 ; lowercase
                shl rdx,10
                cmp eax,C-'0'
                jz .done
        end iterate
.error:
        stc
.done:
        pop rsi
        retn
; RDX - u64, CF=1 on error
; RAX used



GoTime:
namespace GoTime
        virtual at RBP-_FRAME
                        dq ?,?,?,?
                P5      dq ?
                P6      dq ?
                P7      dq ?

                hConOut         dq ?
                hFile           dq ?
                nWritten        dq ?
                rnd_bytes       dq ?
                arg_V           dq ?    ; LocalFree
                arg_N           dd ?,?
dq ?
                _FRAME := $-$$
                assert (_FRAME and $F) = 0
        end virtual
        enter _FRAME,0

        lea rcx,[ctx]           ; PRNG context
        call superkiss64.init

        push STD_OUTPUT_HANDLE
        pop rcx
        call [GetStdHandle]
        mov [hConOut],rax

        call [GetCommandLineW]
        xchg rcx,rax
        lea rdx,[arg_N]
        call [CommandLineToArgvW] ; shell32
        mov [arg_V],rax
        xchg rsi,rax
        cmp [arg_N],3
        jz GotThree
HelpMessage:
        mov rcx,[hConOut]
        lea rdx,[Message]
        mov r8d, sizeof Message
        xor r9,r9
        mov [P5],r9
        call [WriteConsoleW]
OutOfHere:
        invoke ExitProcess,0
        int3

GotThree:
        lodsq ; skip EXE name
        lodsq ; read decimal number
        call wTo_u64
        jc HelpMessage
        mov [rnd_bytes],rdx

        ; try file name
        lodsq
        xchg rcx,rax
        mov edx,GENERIC_WRITE
        xor r8,r8
        xor r9,r9
        mov dword [P5],CREATE_NEW
        mov dword [P6],FILE_ATTRIBUTE_NORMAL
        mov [P7],0
        call [CreateFileW]
        cmp rax,-1 ; INVALID_HANDLE_VALUE
        jz HelpMessage
        mov [hFile],rax

        ; have everything we need
        ; block process in 64k chunks

        mov rbx,[rnd_bytes]
size_block:
        mov esi,BLOCK_SIZE
        sub rbx,rsi
        jnc do_block
        add rsi,rbx
do_block:

        push rsi
        lea rdi,[buffer]
        lea rcx,[ctx]
@@:     call superkiss64.next
        stosq
        sub esi,8
        jnc @b
        add esi,8
        jz rnd_done
@@:     stosb
        shr rax,8
        sub esi,1
        jnz @b
rnd_done:
        pop rsi

        mov rcx,[hFile]
        lea rdx,[buffer]
        mov r8,rsi              ; prng created
        lea r9,[nWritten]
        and [P5],0
        call [WriteFile]
        cmp [nWritten],rsi

        ; TODO: error for bad write

        test rbx,rbx
        jg size_block

        mov rcx,[hFile]
        call [CloseHandle]
        jmp OutOfHere
end namespace

section '.data' data readable writeable

label buffer:BLOCK_SIZE
rb sizeof buffer


align 64
ctx superkiss64.CTX


section '.idata' import data readable writeable
  library kernel32,'KERNEL32.DLL',shell32,'SHELL32.DLL'
  include 'api\kernel32.inc'
  include 'api\shell32.inc'    
...just does what is says on the tin.
(builds with standard distro, just add CommandLineToArgvW and superkiss64 from here)

Made for another project - thrown here incase anyone else wants something for toolbox. Plug in whatever flavor of random you like.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 09 May 2021, 09:31
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4073
Location: vpcmpistri
bitRAKE 10 May 2021, 11:43
Okay, I fixed it so state is maintained across executions - you'll never get the same random data in your lifetime. :P
Code:
; simple program to output random data to file
;
; TODO: test RDSEED/RDRAND is availible
; TODO: make a 32-bit version

BLOCK_SIZE := 1 shl 16 ; increase this if you are more ambitious :P

format PE64 CONSOLE 5.1 ; XP
entry GoTime
include 'win64w.inc'
include 'cpu/ext/rdseed.inc'
include 'cpu/ext/rdrand.inc'

label Message:(Message_end - $)shr 1
TCHAR 10,9,"Random Data File Generator v0.1",10
TCHAR 9,"usage: prngdata {bytes} {file}",10,10
TCHAR 9,"{bytes} will except postfixes of K/k, M/m, or G/g.",10
TCHAR 9,"Multiplier of 2^10, 2^20 or 2^30 respectively.",10,10
TCHAR 9,"{file} cannot exist - will not overwrite.",10
Message_end:

_prngdata_dat TCHAR 'prngdata.dat',0

include 'superkiss64.fasmg' ; random number generator


; RAX - wide-string pointer
wTo_u64: ; (modified for custom parsing)
        push rsi
        xchg rsi,rax
        xor eax,eax
        xor edx,edx
.read:
        imul rdx,rdx,10
        add rdx,rax

        lodsw
        test eax,eax
        jz .done
        sub eax,'0'
        jc .done ; error
        cmp eax,10
        jc .read
        cmp word [rsi],0
        jnz .error
        ; minimal overflow checking, could probably set more bits ;)
        mov rsi,$FFC0'0000'0000'0000
        and eax,not $20 ; uppercase
        iterate C, 'K','M','G'
                test rdx,rsi
                jnz .error
                shl rdx,10
                cmp eax,C-'0'
                jz .done
        end iterate
.error:
        stc
.done:
        pop rsi
        retn
; RDX - u64, CF=1 on error, ZF=1 on success
; RAX used



GoTime:
namespace GoTime
        virtual at RBP-_FRAME
                        dq ?,?,?,?
                P5      dq ?
                P6      dq ?
                P7      dq ?

                hFile           dq ?
                nWritten        dq ?
                rnd_bytes       dq ?
                arg_V           dq ?    ; LocalFree
                arg_N           dd ?,?

                _FRAME := $-$$
                assert (_FRAME and $F) = 0
        end virtual
        enter _FRAME,0
        call [GetCommandLineW]
        xchg rcx,rax
        lea rdx,[arg_N]
        call [CommandLineToArgvW] ; shell32
        mov [arg_V],rax
        xchg rsi,rax
        cmp [arg_N],3
        jz GotThree
HelpMessage:
        push STD_OUTPUT_HANDLE
        pop rcx
        call [GetStdHandle]

        xchg rcx,rax
        lea rdx,[Message]
        mov r8d, sizeof Message
        xor r9,r9
        mov [P5],r9
        call [WriteConsoleW]
OutOfHere:
        xor ecx,ecx
        call [ExitProcess]
        int3

GotThree:
        lodsq ; skip EXE name
        lodsq ; read decimal number
        call wTo_u64
        jc HelpMessage
        mov [rnd_bytes],rdx

        ; try file name
        lodsq
        xchg rcx,rax
        mov edx,GENERIC_WRITE
        xor r8,r8
        xor r9,r9
        mov dword [P5],CREATE_NEW
        mov dword [P6],FILE_ATTRIBUTE_NORMAL
        mov [P7],0
        call [CreateFileW]
        cmp rax,-1 ; INVALID_HANDLE_VALUE
        jz HelpMessage
        mov [hFile],rax

; try to read "prngdata.data". must be exactly sizeof superkiss64.CTX bytes:
        lea rcx,[_prngdata_dat]
        mov edx,GENERIC_READ
        xor r8,r8
        xor r9,r9
        mov dword [P5],OPEN_EXISTING
        mov dword [P6],FILE_ATTRIBUTE_NORMAL
        mov [P7],0
        call [CreateFileW]
        cmp rax,-1 ; INVALID_HANDLE_VALUE
        jz no_state_cache_file
        xchg rbx,rax

        mov rcx,rbx
        lea rdx,[ctx]
        mov r8,sizeof superkiss64.CTX
        lea r9,[nWritten]
        and [P5],0
        call [ReadFile]
        mov rcx,rbx
        call [CloseHandle]

; DO NOT change data file if it's something unexpected, just quit

        cmp [nWritten],sizeof superkiss64.CTX
        jnz HelpMessage

no_more_prep:
        ; have everything we need
        ; block process in 64k chunks

        mov rbx,[rnd_bytes]
size_block:
        mov esi,BLOCK_SIZE
        sub rbx,rsi
        jnc do_block
        add rsi,rbx
do_block:

        push rsi
        lea rdi,[buffer]
        lea rcx,[ctx]
@@:     call superkiss64.next
        stosq                           ; okay to overwrite when not MOD 8
        sub esi,8
        ja @b
        pop rsi

        mov rcx,[hFile]
        lea rdx,[buffer]
        mov r8,rsi                      ; prng created
        lea r9,[nWritten]
        and [P5],0
        call [WriteFile]
        cmp [nWritten],rsi

        ; TODO: error for bad write

        test rbx,rbx
        jg size_block

        mov rcx,[hFile]
        call [CloseHandle]

; try to save "prngdata.dat"
        lea rcx,[_prngdata_dat]
        mov edx,GENERIC_WRITE
        xor r8,r8
        xor r9,r9
        mov dword [P5],CREATE_ALWAYS
        mov dword [P6],FILE_ATTRIBUTE_NORMAL
        mov [P7],0
        call [CreateFileW]

        ; guess we could loop forever? Maybe device is readonly, or no permissions?

        cmp rax,-1 ; INVALID_HANDLE_VALUE
        jz HelpMessage
        xchg rbx,rax

        mov rcx,rbx
        lea rdx,[ctx]
        mov r8,sizeof superkiss64.CTX
        lea r9,[nWritten]
        and [P5],0
        call [WriteFile]
        mov rcx,rbx
        call [CloseHandle]

        ; this message gets overworked, we're not trying to diagnose device errors

        cmp [nWritten],sizeof superkiss64.CTX
        jnz HelpMessage
        jmp OutOfHere
end namespace

; maybe use Advapi32.dll, CryptGenRandom()
no_state_cache_file:
        ; also randomize other parameters
        mov ecx,superkiss64.Q_MAX + 3
.get_some:
        rdseed rax
        jc @f
        rdseed rax
        jc @f
        rdrand rax
        jc @f
        rdtsc
        xor eax,edx
        mul qword [dword 0x7FFE0008] ; use KUSER_SHARED_DATA.InterruptTime
@@:     mov [ctx.xcng + rcx*8 - 8],rax
        loop .get_some
        ; reset state to indicate data is good
        mov [ctx.index],0
        jmp GoTime.no_more_prep



align 64
ctx superkiss64.CTX


align 4096
label buffer:BLOCK_SIZE
rb sizeof buffer


section '.idata' import data readable writeable
  library kernel32,'KERNEL32.DLL',shell32,'SHELL32.DLL'
  include 'api\kernel32.inc'
  include 'api\shell32.inc'    

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 10 May 2021, 11:43
View user's profile Send private message Visit poster's website Reply with quote
Aiwan



Joined: 10 May 2021
Posts: 4
Aiwan 11 May 2021, 18:50
Code:
format binary as "txt"

virtual at 0
        zzz::
        rb 20
end virtual

macro srand x* {rand_seed = x}

macro rand x*,rmin*,rmax* {
        rand_seed = ((rand_seed*1103515245)+12345) and 0xffffffff
        x = (rand_seed shr 16) and 0x7fff
        ;x = rand_seed
        x = (x mod (rmax-rmin+1)) + rmin


}

macro display_decimal x* {
  local ..v
  ..v = x
        virtual at 0
                repeat 20
                        if ..v = 0
                                break
                        else
                                db (..v mod 10) + '0'
                                ..v = ..v / 10
                        end if
                end repeat
                if $ = 0
                        display '0'
                else
                        repeat $
                                load ..v byte from $ - %
                                display ..v
                        end repeat
                end if
        end virtual
}

macro save_txt txt* {
  local ..lc
  local ..size
  local ..a

        ..lc = txt

        virtual zzz
          ..size = 0
                repeat 20
                        if ..lc = 0
                                if ..size <> 0
                                        break
                                else
                                        store byte ..lc at 0
                                        ..size = 1
                                        break
                                end if
                        else
                                ..a = ..lc mod 10
                                store byte ..a at 0+%-1
                                ..lc = ..lc / 10
                                ..size = ..size+1
                        end if
                end repeat
        end virtual

        repeat ..size
                load ..a byte from zzz:0+..size-%
                db ..a+48
        end repeat
        db 13,10
}

srand %t
repeat 25
        rand value,0,9   ;метка вместо rand_number
        save_txt value

end repeat    
Post 11 May 2021, 18:50
View user's profile Send private message Reply with quote
Aiwan



Joined: 10 May 2021
Posts: 4
Aiwan 11 May 2021, 18:53
Code:
format binary as "txt"

macro srand x* {rand_seed = x}

macro rand x*,rmin*,rmax* {
        rand_seed = ((rand_seed*1103515245)+12345) and 0xffffffff
        x = (rand_seed shr 16) and 0x7fff
        ;x = rand_seed
        x = (x mod (rmax-rmin+1)) + rmin
}

;===========================================================

srand %t
sizeFile = 1024;1073741824   
while sizeFile >= 0
        rand value,2,50  
        if value < sizeFile
                repeat value - 1
                        rand char,65,90
                        db char
                end repeat
        else
                repeat sizeFile - 1
                        rand char,65,90
                        db char
                end repeat
        end if
        db 10
        sizeFile = sizeFile - value
end while    


fasm1
Post 11 May 2021, 18:53
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4073
Location: vpcmpistri
bitRAKE 22 Apr 2022, 00:24
https://espadrine.github.io/blog/posts/shishua-the-fastest-prng-in-the-world.html

An okay PRNG largely based on work by Thaddée Tyl, CC0 license.

Found another random number generator! Of course, I coded it in x64 and timed it. I've opted for a very strange calling convention, but it aligned the code favorably. On one machine here it easily does 40+ GiB/s ( > 10 bytes/cycle, single core ). He does claim it's the fastest in the world!

Tune it for your L1 cache and let me know how it does?

(mywin.inc required to build.)


Description: x64 AVX2 PRNG w/ timing test.
Download
Filename: shishua.zip
Filesize: 2.96 KB
Downloaded: 459 Time(s)


_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 22 Apr 2022, 00:24
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.