News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

A quick question & answer #2 pre processing things at building time

Started by LordAdef, February 07, 2019, 08:44:19 AM

Previous topic - Next topic

LordAdef

Hello my friends again,
Another quick question & answer...
Say it we have the below common scenario:
QuoteYou need to fill an array with random values every time you program runs.

Instead of doing this, is there a way to make this be done at building time?
Does something like this exist?
PREPROCESS
    .data?
       array bla bla bla
    .code
    mov ecx, 50
    preFill:
    mov array[ecx], ecx
    loop preFill
PREPROCESS end

cheers, Alex

ps: Could we use the MACRO functionality as a way to achieve this, somehow?

daydreamer

Quote from: LordAdef on February 07, 2019, 08:44:19 AM
Hello my friends again,
Another quick question & answer...
Say it we have the below common scenario:
QuoteYou need to fill an array with random values every time you program runs.

Instead of doing this, is there a way to make this be done at building time?
Does something like this exist?
PREPROCESS
    .data?
       array bla bla bla
    .code
    mov ecx, 50
    preFill:
    mov array[ecx], ecx
    loop preFill
PREPROCESS end

cheers, Alex

ps: Could we use the MACRO functionality as a way to achieve this, somehow?
start qeditor and check help menu for macros,there is even ways of conditional assembly
I seen it in a firedemo code,there is several palettes made this way,flame in different colors and IF variable=1  ;blue,code a bluewhite palette
.IF .ENDIF .WHILE etc has a dot for assembly code conditionals,macros conditional code uses no dot IF's etc and looks more like pseudocode
targeting cpus in older times,you could have conditional assembly depending on you want masm to assemble,MMX code,SSE code,SSE2 code or code that only uses general cpu/fpu instructions
I dont know if there is an RANDOM function,if not you just need to adapt a randomgenerator code to MACRO type of code

look for MASM reference help in qeditor
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

LordAdef

hi daydreamer,
Maybe I didn't express myself correctly.
I want to generate something like filling an array at building time, and have it inbeded in my code so I don't have to do it at runtime.

daydreamer

Quote from: LordAdef on February 07, 2019, 09:27:32 AM
hi daydreamer,
Maybe I didn't express myself correctly.
I want to generate something like filling an array at building time, and have it inbeded in my code so I don't have to do it at runtime.
this describes how DUP works,it can be used both with ? and numbers

count DUP (initialvalue [,initialvalue]...)
use this in .data section
array dd 10000 DUP(50)
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

jj2007

include \masm32\include\masm32rt.inc

.data
tmp$ CATSTR <MyArray dd 100>
tmpCt=100
repeat 40
  tmp$ CATSTR tmp$, <, >, %tmpCt
  tmpCt=tmpCt+1
ENDM
% echo tmp$
tmp$

HelloW$ db "Hello World", 0

.code
start:
  xor ebx, ebx ; set two non-volatile
  xor esi, esi ; registers to zero
  .Repeat
add esi, MyArray[4*ebx]
inc ebx
  .Until ebx>=lengthof MyArray
  MsgBox 0, cat$(str$(esi), " is the sum"), offset HelloW$, MB_OK
  exit

end start

Raistlin

Thanks guys [daydreamer & jj2007] for the macro & dup ideas, as well as LordAdef for posting the original question.
I'll definitely be looking into the possibilities for application.

Just my 2 cents. Might I add that data load times from HDD are significantly slower [specifically for Windows apps],
than the processing time to create the same data set result in most circumstances. My thoughts are, from potentially
erroneous experience, that a calculated lookup table [< 16MB] would benefit from calculation rather than static load
from storage.  Latency of perhaps 100's of ms to multiple seconds [system load dependent] may erstwhile result.
Assuredly larger lookup tables should be pre-calculated, which bloats the application - but gets you to the app landing
page quicker. It's a balancing act, as per an old 'hutch-ism' - speed test everything and make your decision dependent
on your need.
Are you pondering what I'm pondering? It's time to take over the world ! - let's use ASSEMBLY...

hutch--

Alex,

Two questions, how big is the random array and how random does it need to be. The size matters as it has to be written somewhere, either as data which is loaded at runtime or directly as mnemonics which then produces a problem in feeding anything like random numbers. Either approach will produce large increases in the exe size if the member count is big.

Generating the array dynamically can be very fast if you design it correctly and it can be done in allocated memory without blowing out the size of the exe.

jj2007

Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
48 ms for filling a 10.00 MB array


Source:

include \masm32\MasmBasic\MasmBasic.inc         ; download

.data?
FatArray        dd 1024*1024*10 dup(?)

  Init
  xor ecx, ecx
  PrintCpu 0
  NanoTimer()
  .Repeat
        mov FatArray[4*ecx], Rand(-1)
        inc ecx
  .Until ecx>=lengthof FatArray
  Inkey NanoTimer$(), Str$(" for filling a %3f MB array", ecx/1024/1024)
EndOfCode

daydreamer

here is some example code I seen what you can do with macro and conditional assembly creating data

i = 1
repeat 15
   db 255, i, 0
   i = i + 2
endm

you can use several of these to create data and combine with DUP
maybe if you are skilled enough you can translate a simple random generator to this kind of code

and you also put conditional assembly between these statements:
IFDEF name

ENDIF

edit:
looked thru some old democode, it says "The map is just a pre-generated recursive subdivision."
so question is it possible with masm macro engine make recursive landscape generating code?
@Hutch
things not possible with masm macro engine,is it easier with qeditor script engine?

my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

jj2007

Quote from: daydreamer on February 07, 2019, 11:18:05 PMmaybe if you are skilled enough you can translate a simple random generator to this kind of code

It is probably possible, but is it useful? You generate dd nnn in the .data section, i.e. you are bloating your exe. Given that you can do the same in the .data? section at a rate of 5 milliseconds per Million DWORDs, where is the point?

daydreamer

Quote from: jj2007 on February 08, 2019, 12:35:55 AM
Quote from: daydreamer on February 07, 2019, 11:18:05 PMmaybe if you are skilled enough you can translate a simple random generator to this kind of code

It is probably possible, but is it useful? You generate dd nnn in the .data section, i.e. you are bloating your exe. Given that you can do the same in the .data? section at a rate of 5 milliseconds per Million DWORDs, where is the point?
curiosity whats can be done with macros at the same time a macro exercise?
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

jj2007

Have fun:
include \masm32\include\masm32rt.inc
include rand.mac
.data
elements=10000
MyArray LABEL DWORD
REPEAT elements
dd rand()
ENDM
.code
start:
  mov esi, offset MyArray
  .Repeat
lodsd
print str$(eax), 13, 10
test esi, 31
.if Zero?
inkey chr$("more (n)?", 13)
invoke GetKeyState, VK_N
test ah, ah
.break .if Sign?
.endif
  .Until esi>=offset MyArray+4*elements
  invoke ExitProcess, 0
end start


Build with UAsm if you want more than 10,000 DWORD elements. MASM will choke with various nonsense error messages.
UAsm has no limits, apparently, but if you use limits=1000000 (one Million elements), building the source will take a quarter of an hour. You have been warned 8)

LordAdef

Quote from: hutch-- on February 07, 2019, 06:19:18 PM
Alex,

Two questions, how big is the random array and how random does it need to be. The size matters as it has to be written somewhere, either as data which is loaded at runtime or directly as mnemonics which then produces a problem in feeding anything like random numbers. Either approach will produce large increases in the exe size if the member count is big.

Generating the array dynamically can be very fast if you design it correctly and it can be done in allocated memory without blowing out the size of the exe.
Thanks for that, Hutch!The random numbers were purely as a theoretical example (although I am in fact using a pre processed random LUT).
i am currently generating may array dynamically. But I am not allocating memory dinamically. I am using a predefined structure space for that, and avoiding any memory leaks.
But your point of allocating memory for that is actually quite sound for what I need to do.
Question: can I alloc memory and define a structure design for that memory?

LordAdef

Quote from: jj2007 on February 08, 2019, 01:50:19 AM
Have fun:
include \masm32\include\masm32rt.inc
include rand.mac
.data
elements=10000
MyArray LABEL DWORD
REPEAT elements
   dd rand()
ENDM
.code
start:
  mov esi, offset MyArray
  .Repeat
   lodsd
   print str$(eax), 13, 10
   test esi, 31
   .if Zero?
      inkey chr$("more (n)?", 13)
      invoke GetKeyState, VK_N
      test ah, ah
      .break .if Sign?
   .endif
  .Until esi>=offset MyArray+4*elements
  invoke ExitProcess, 0
end start


Build with UAsm if you want more than 10,000 DWORD elements. MASM will choke with various nonsense error messages.
UAsm has no limits, apparently, but if you use limits=1000000 (one Million elements), building the source will take a quarter of an hour. You have been warned 8)
Thanks Jochen, that was certainly instructive. I never tried running code within the .data section, although I knew it was possible.
You always learn something new when we ask question!

jj2007

Quote from: LordAdef on February 08, 2019, 02:40:40 AMQuestion: can I alloc memory and define a structure design for that memory?

Certainly:

  Dim MyRect() As RECT
  For_ ecx=0 To 99
        mov MyRect(ecx, left), Rand(100)
        mov MyRect(ecx, bottom), Rand(100)
  Next


Quote from: LordAdef on February 08, 2019, 02:43:06 AM
I never tried running code within the .data section, although I knew it was possible.

Running code in .data is possible but a pretty exotic exercise. But that is not what the macro is doing: It actually generates dd 123 entries. It's data, not instructions.