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?
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
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.
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)
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
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.
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.
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
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?
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?
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?
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)
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?
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!
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)
NextQuote 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.
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?
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]
mov esi, offset TheRect
mov edx, (RECT PTR [esi[5*sizeof RECT]]).bottom :t
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