flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Macro to define String constants.

Author
Thread Post new topic Reply to topic
S.T.A.S.



Joined: 09 Jan 2004
Posts: 173
Location: Ru#27
S.T.A.S. 03 Mar 2004, 11:58
Hi, all!
Here is the set of macros to define string constants.

With DB directive we should manually check is a string defined in the source once or more, otherwise we'll get some data doublication. This is easy with small projects, but may be very hard in big ones (especially with modules).

An example of use:
Code:
invoke       MessageBox,0,text,caption,0
invoke   MessageBox,0,text2,caption2,0
........
.const.sz  text,'text',caption,'caption'
.const.sz  text2,'text',caption2,'caption'    

Somewhere at the end of *.asm put this: .const.sz.include ..const.sz
Also, .const.sz macro could be integrated into invoke one, to make things easier.

Code:
macro        .const.sz       [pointer, text]
 {      forward .const.sz.define        pointer, text, ..const.sz }


macro       .const.sz.define        pointer, text, dummy,[ptrs,strings]
 {  common  if      text in <strings> ;;  is text already defined?
                        pointer#.def = FALSE    ;;  then define a flag
              end if
      forward if      defined pointer#.def
                if      text eq strings & pointer#.def = FALSE
                  pointer = ptrs          ;;  use ptr to defined string
                       pointer#.def = TRUE     ;;  no need to define twice
         end if
              end if
      common  ..const.sz      fix ..const.sz,pointer,text     ;;  add to the list
 }

macro     .const.sz.include       dummy,[pointer,text]
 { forward if      ~ pointer eq    ;;  mey be no strings are defined
                   if      ~ defined       pointer#.def
                                pointer = $
                         db      text,0
                      end if
              end if }    


Thank you for comments & bug reports..
Regards
Post 03 Mar 2004, 11:58
View user's profile Send private message Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 01 Jun 2004, 00:19
Hi all.
These days I implemented these macroses in the project Fresh and converted almost all string constants to this format.
Unfortunately there is one big problem with this macro set - the compiler speed decrease as far as twice:

Without constant macroses:
Total time: 18.023s
preprocessing: 6.822s
Parsing: 1.321s
Assembling time: 8.569s (79 passes)

With constant macroses:
Total time: 42.867s
preprocessing: 21.242s
parsing: 3.099s
Assembling time: 17.057s (79 passes)

So, I find these macroses highly useful, but the performance degradation is too big to be appropriate...
Some ideas?...

Regards.
Post 01 Jun 2004, 00:19
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
comrade



Joined: 16 Jun 2003
Posts: 1150
Location: Russian Federation
comrade 01 Jun 2004, 02:43
get a faster computer

_________________
comrade (comrade64@live.com; http://comrade.ownz.com/)
Post 01 Jun 2004, 02:43
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 01 Jun 2004, 02:47
comrade wrote:
get a faster computer


Even on faster computer twice slower will be twice slower. Smile
Post 01 Jun 2004, 02:47
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
decard



Joined: 11 Sep 2003
Posts: 1092
Location: Poland
decard 01 Jun 2004, 13:53
further optimizations to preprocessor? (if they're possible)

and why assembly time has increased? macros are processed by preprocessor, aren't they?
Post 01 Jun 2004, 13:53
View user's profile Send private message Visit poster's website Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 01 Jun 2004, 14:04
decard wrote:
further optimizations to preprocessor? (if they're possible)

and why assembly time has increased? macros are processed by preprocessor, aren't they?


There is "if text in <strings> " operator, that will be processed in assembly stage. This macroses are interesting namely with loading equally preprocessor and assembler Sad
Post 01 Jun 2004, 14:04
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 01 Jun 2004, 15:03
Processing the "eq" and "in" comparisions in parser instead of assembler is already on the TODO list (also, if conditional expression can be evaluated without doubt at the parsing stage, the whole "if" block should be processed at this stage). However, I cannot promise I'll be able to implement it very soon.
Post 01 Jun 2004, 15:03
View user's profile Send private message Visit poster's website Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 01 Jun 2004, 16:18
Privalov wrote:
Processing the "eq" and "in" comparisions in parser instead of assembler is already on the TODO list (also, if conditional expression can be evaluated without doubt at the parsing stage, the whole "if" block should be processed at this stage). However, I cannot promise I'll be able to implement it very soon.


Yea, this is good idea, because it will remove processing from multipass assembly stage, but IMHO, this can't solve above constants definition problem. Using this macro leads to every next defined string constant checks all previously defined constants - that leads to O(n^2)...

Regards
Post 01 Jun 2004, 16:18
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 01 Jun 2004, 17:09
You might try adding some hash calculation for faster comparisions - fasm's assembly-time "repeat" and "if" abilities allow it.

Or you can add an option to disable those check for the work stage compilations, and enable it only for final assembly, when you need to get the optimized executable.
Post 01 Jun 2004, 17:09
View user's profile Send private message Visit poster's website Reply with quote
S.T.A.S.



Joined: 09 Jan 2004
Posts: 173
Location: Ru#27
S.T.A.S. 02 Jun 2004, 16:14
Hmm.. if text in <strings> is used (I hope) to speed up the macro.
Slow forward block should only be processed if string is already defined earlier.

I guess this set of macro is a bit lame Very Happy
Unfortunately, my computer is rather fast and my projects are quite small to notice real speed difference in variants Sad


And one thing (it's offtopic, but has some relation to compiling speed)
One frend of mine send me a mail with nearly such content (sorry for translation):
Quote:

Project: compare compilation time of 2 macro design's modes.
Tools: FASM v1.52 console, Windows XP Pro, Celeron 500 Mhz, 320 Mb.

Description of operation:

Boot system with minimal tasks & services loaded.

Macro to generate big file:
Code:
;-----------------------------------
;temp1.asm
;-----------------------------------
db 'temp\', 13, 10
times 5000 db 'arg,\', 13, 10
db 'arg'
;-----------------------------------    
compile: FASM temp1.asm temp1.com
rename: temp1.com -> temp2.asm
make a copy of temp2.asm and rename it to temp3.asm

At the beginning of temp2.asm & temp3.asm add respectively:
Code:
;-----------------------------------
; temp2.asm
;-----------------------------------
macro temp [Arg]
{
  forward
    if ~ Arg eq
      display `Arg, 13, 10
    end if
}
;-----------------------------------

;-----------------------------------
; temp3.asm
;-----------------------------------
macro temp [Arg]
{
    common
      if ~ Arg eq
        forward
          display `Arg, 13, 10
        common
      end if
}
;-----------------------------------    
Bath file for compilation
Code:
***************************************************
@echo off
echo ------------------------------------
echo temp2.asm
echo ------------------------------------
fasm temp2.asm temp
fasm temp2.asm temp
fasm temp2.asm temp
fasm temp2.asm temp
fasm temp2.asm temp

echo ------------------------------------
echo temp3.asm
echo ------------------------------------
fasm temp3.asm temp
fasm temp3.asm temp
fasm temp3.asm temp
fasm temp3.asm temp
fasm temp3.asm temp

pause
***************************************************    
Compiling time: temp2.asm ~ 2.8с, а temp3.asm ~ 2.4с.

That's Ok.


Here's another thing:
Code:
***************************************************
;-----------------------------------
; temp3.asm
;-----------------------------------
macro temp [Arg]
{
  common
    if ~ Arg eq
      forward
        db `Arg, 13, 10
      common
    end if
}
;-----------------------------------

temp\
....
***************************************************


***************************************************
;-----------------------------------
; temp3.asm
;-----------------------------------
macro temp [Arg]
{
  common
    if ~ Arg eq
      forward
        db `Arg, 13, 10
      common
    end if
}
;-----------------------------------
temp\
....
***************************************************    

Notice blank line between comment and temp\ in the first case.

Compiling time: 1st case ~ 2.4с 2nd, case ~ 1.0с.


I did the same test with:
FASM v1.52 console, Windows XP Home SP1, AthlonXP2000+ @1667Mhz, 512Mb DDR266.

My results differ a lot:
For the first test 0.8с & 0.3с. And 0.4с & 0.3с for the second.

I think there are lot of things that affects such tests and tests are too synthetic, but these examples show that smal changes in macros could give noticeable results. Too bad I'm not good with FASM internals to understend such details and use the power Sad
Post 02 Jun 2004, 16:14
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20513
Location: In your JS exploiting you and your system
revolution 31 Aug 2004, 07:10
One thing I noticed with a similar macro I was using for a while was that for a large project I was working with the assemble time would gradually increase as I added more strings to the list. But eventually the project became too complex and the command line version of fasm gave up with out of an out of memory error.

I had to abandon the macro and manually make each string with a label then alter all places I was using the string.

In fact I used it with my invoke macro so that strings were reused if more than one invoke statement had the same string constant in it.

The actual size of the executable at the time the memory error came up was only 33k. At the time my machine had 512Meg on-board but by using the task manager I noticed that fasm was allocating only ~256Meg before failing.
Post 31 Aug 2004, 07:10
View user's profile Send private message Visit poster's website Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 31 Aug 2004, 09:45
Unfortunately, the comparisons with previous defined strings, in order to prevent duplications, uses very bad algorithm with speed O(n^2). So, the compilation speed decrease very fast with increasing string count.
That was the reason I refused this check in Fresh library and now Fresh simply defines every string without checking.
The result is only several hundreds bytes of duplicated data and at least twice faster compilation.
Of course we need such constants data definitions, but IMHO, we need some new approach to it.

Regards.
Post 31 Aug 2004, 09:45
View user's profile Send private message Visit poster's website ICQ Number 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.