The MASM Forum

General => The Campus => Topic started by: LordAdef on February 07, 2019, 08:44:19 AM

Title: A quick question & answer #2 pre processing things at building time
Post by: 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?
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: daydreamer on February 07, 2019, 09:15:58 AM
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
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: 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.
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: daydreamer on February 07, 2019, 09:37:56 AM
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)
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: jj2007 on February 07, 2019, 09:46:55 AM
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
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: Raistlin on February 07, 2019, 04:24:31 PM
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.
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: 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.
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: jj2007 on February 07, 2019, 10:28:14 PM
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 (http://masm32.com/board/index.php?topic=94.0)

.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
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: daydreamer on February 07, 2019, 11:18:05 PM
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?

Title: Re: A quick question & answer #2 pre processing things at building time
Post by: 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?
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: daydreamer on February 08, 2019, 12:44:10 AM
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?
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: 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)
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: LordAdef on February 08, 2019, 02:40:40 AM
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?
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: LordAdef on February 08, 2019, 02:43:06 AM
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!
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: jj2007 on February 08, 2019, 05:31:01 AM
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.
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: LordAdef on February 08, 2019, 06:41:10 AM
Quote  Dim MyRect() As RECT
  For_ ecx=0 To 99
        mov MyRect(ecx, left), Rand(100)
        mov MyRect(ecx, bottom), Rand(100)
  Next
I understand you masmBasic, clear. 
In terms of Masm, I would imagine 
1.alloc the sizeof my myStruct 
2. use "assume" the ptr as myStruct 
Does that make sense, right? Is there another way in masm/masm32?
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: jj2007 on February 08, 2019, 07:58:52 AM
There are various ways to achieve that, for example
.data?
TheRect RECT 20 dup(<>)

.code
start:
  mov esi, offset TheRect
  mov ecx, 5  ; rectangle #5
  imul eax, ecx, RECT
  mov edx, [esi+eax.RECT.bottom]
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: aw27 on February 08, 2019, 04:51:59 PM
mov esi, offset TheRect
mov edx, (RECT PTR [esi[5*sizeof RECT]]).bottom  :t
Title: Re: A quick question & answer #2 pre processing things at building time
Post by: jj2007 on February 08, 2019, 08:06:51 PM
Nice :t

Here are two more:
include \masm32\include\masm32rt.inc ; pure Masm32

MyRect equ [esi.RECT] ; equates are a nice option

Rect MACRO index, element
  if (opattr index) eq 36
EXITM <TheRect[index*RECT][RECT.element]>
  else
imul eax, index, RECT ; register or memvar
add eax, offset TheRect
exitm <[eax.RECT.&element]>
  endif
ENDM

.data
TheRect RECT 5 dup (<>)
.code
start:

  mov esi, offset TheRect
  m2m ebx, 5

  mov MyRect.bottom[5*RECT], 100
  print str$(Rect(ebx, bottom)), 9, "Rect(ebx, bottom)", 13, 10
  mov edx, Rect(ebx, bottom)
  inc edx
  mov Rect(ebx, bottom), edx
  print str$(Rect(ebx, bottom)), 9, "Rect(ebx, bottom)", 13, 10
  inc Rect(ebx, bottom)
  inkey str$(Rect(5, bottom)), 9, "Rect(5, bottom)", 13, 10
  exit

end start