flat assembler
Message board for the users of flat assembler.

Index > Main > 2013-Oct - flat assembler 1.71.14

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 25 Oct 2013, 12:55
In this release I introduce one more experimental feature, one that should allow to make easier to use macro packages or header sets.

The new "postpone" directive allows to define an anonymous macro that will automatically get expanded when preprocessor reaches the end of the source.

For example, if you design some custom headers for Win32 programming and you want to automatically generate import section at the end of image without requiring from programmer to use some special macro at the end of source (like the ".end" macro in case of fasm's official extended headers), you can put this definition into you header file:

Code:
postpone {

   section '.idata' import data readable writeable

     library kernel32,'KERNEL32.DLL',\
             user32,'USER32.DLL',\
             gdi32,'GDI32.DLL',\
             advapi32,'ADVAPI32.DLL',\
             comctl32,'COMCTL32.DLL',\
             comdlg32,'COMDLG32.DLL',\
             shell32,'SHELL32.DLL',\
             wsock32,'WSOCK32.DLL'

     include 'api\kernel32.inc'
     include 'api\user32.inc'
     include 'api\gdi32.inc'
     include 'api\advapi32.inc'
     include 'api\comctl32.inc'
     include 'api\comdlg32.inc'
     include 'api\shell32.inc'
     include 'api\wsock32.inc'

}
    


If there are multiple "postpone" macros defined in source, they are executed in the order in which they were defined.
Post 25 Oct 2013, 12:55
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 25 Oct 2013, 13:01
And now the example that combines the string pool management macros I created to demonstrate the feature of labeled addressing spaces with the "postpone" to create a simple to use macro package.

This goes into STR.INC:
Code:
virtual at 0
  __str__character_skips::
  dd 256 dup ?
end virtual

struc str [data] {
 common local ..buffer,size,a,b,c,p,skip,found

  virtual at 0
    ..buffer:: db data
    size = $
  end virtual

  times 256 store dword size at __str__character_skips:(%-1)*4
  repeat size-1
    load a byte from ..buffer:%-1
    store dword size-% at __str__character_skips:a*4
  end repeat

  found = -1
  p = 0
  while p + size <= __str__current & p + size <= __STR__DATA_SIZE
    c = size
    while c > 0
      load a byte from __str__section:__str__data+p+c-1
      load b byte from ..buffer:c-1
      if a<>b
        c = -1
        break
      end if
      c = c - 1
    end while
    if c = 0
      found = p
      break
    else
      load a byte from __str__section:__str__data+p+size-1
      load skip dword from __str__character_skips:a*4
      p = p + skip
    end if
  end while

  if found >= 0
    label . at __str__data + found
  else
    label . at __str__data + __str__current
    __str__current = __str__current + size
    if __str__current <= __STR__DATA_SIZE
      repeat size
        load a byte from ..buffer:%-1
        store byte a at __str__section:.+%-1
      end repeat
    end if
  end if
}

define __str__cnt 0

struc str [data] {
 common
   rept 1 i:__str__cnt+1 \{
     define __str__cnt i
     define __str__\#i . str data
   \}
}

macro __str__previous {}

macro .str {
  __str__section::
  __str__data db __STR__DATA_SIZE dup 0
  __str__current = 0
  restruc str
  rept __str__cnt i \{ match def,__str__\#i \\{ def \\} \}
}

postpone {
  __STR__DATA_SIZE = __str__current
}    
The only modification to the previous version of these macros is that the "macro .end" has been changed to "postpone".
This allows the simplified usage:
Code:
include 'str.inc'

some_message str 'Testing one',0

.str    ; the data of all strings is put here

other_message str 'Doing something...',13,10

        mov     eax,some_message
        mov     ebx,submessage
        mov     ecx,other_message

submessage str 'one',0    
Post 25 Oct 2013, 13:01
View user's profile Send private message Visit poster's website Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1905
DOS386 25 Oct 2013, 18:12
> In this release I introduce one more experimental feature

Thus there is a risk that it's going to vanish in future ?

Code:
version 1.71.14 (Oct 25, 2013)

[+] Added "postpone" directive to preprocessor.

version 1.71.13 (Sep 09, 2013)

[-] Fixed a bug that caused the expressions containing external symbols
    to overflow from time to time.
    


> The new "postpone" directive allows to define an anonymous macro
> that will automatically get expanded when preprocessor reaches
> the end of the source.

Interesting ... Smile ... but isn't it against the design ?

Quote:

The ORG directive in my version allows to design code to work correctly when loaded at specified origin, while its placement in file is just determined by the order of source. My assembler, generating the code in flat addressing space, was always outputting the code exactly in the same order, as it was defined in source. Thus came the name for it - flat assembler.
Post 25 Oct 2013, 18:12
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 25 Oct 2013, 19:00
DOS386 wrote:
Interesting ... Smile ... but isn't it against the design ?
No more than a regular macro definition and usage. This is just a handy shortcut so that you don't need to call the macro by its name at the end of the file.

One of my early (and not very serious) ideas for this feature was to allow defining macro with name being the EOF character, so that when the EOF was encountered, the macro would be expanded. Wink


Last edited by Tomasz Grysztar on 25 Oct 2013, 19:13; edited 2 times in total
Post 25 Oct 2013, 19:00
View user's profile Send private message Visit poster's website Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 25 Oct 2013, 19:07
It works nicely for data:
Code:
macro @crc8 s,e
{
        local lbl
    lbl:
        db 0
        postpone
        \{
                store byte (e - s) at lbl
        \}
}

s:
db 'A'
@crc8 s,e
db 'B'
e:    
Which avoids the previous issue of having something messy like:
Code:
s:
db 'A'
crc_1:
db 0
db 'B'
e:

@crc8 crc_1,s,e    
I can't see it being that useful for code unless you go a little crazy with it:
Code:
macro DoIt
{
        xor eax,eax

        postpone
        \{
                not eax
        \}
}

postpone
{
        procA:

                DoIt

                inc eax

        postpone
        \{
                ret

                procB:

                        DoIt

                        dec eax

                postpone
                \\{
                        ret
                \\}
        \}
}
    
Very Happy
Post 25 Oct 2013, 19:07
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 25 Oct 2013, 19:12
cod3b453 wrote:
I can't see it being that useful for code unless you go a little crazy with it
Using it for code definitely IS crazy. Smile
This feature is only really useful to make it easier to design some complex headers and/or macro packages, that require some of the things to be calculated after all the data from all the source code has been gathered, etc.
Post 25 Oct 2013, 19:12
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 25 Oct 2013, 19:42
Seems like a nice improvement considering the load/store use case pointed out by cod3b453. It is a bit sad, that it renders useless some of my nifty tricks I used to avoid defining "put-this-in-the-end" kind of macros.

I'm also glad to note, it perfectly passed my play-around-tests like this one:
Code:
postpone
{
        postpone \{ m1 \}
        display '2',13,10
        macro m1 \{ postpone \\{ display '6',13,10 \\} display '4',13,10 \}
}
postpone
{
        postpone \{ m2 \}
        display '3',13,10
        macro m2 \{ postpone \\{ display '7',13,10 \\} display '5',13,10 \}
}
display '1',13,10    


However, I find reporting of errors occurring within expanded postpone macroblocks a bit misleading:
Code:
postpone { err }
display 'Hello',13,10    

produces
Code:
flat assembler  version 1.71.14  (1572864 kilobytes memory)
Hello
C:\asm.asm [2]:
display 'Hello',13,10
C:\asm.asm [1] postpone [0]:
postpone { err }
error: error directive encountered in source file.    

And if there's a newline at the end, then the '\n' character is reported to produce an error.

_________________
Faith is a superposition of knowledge and fallacy
Post 25 Oct 2013, 19:42
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 25 Oct 2013, 20:00
l_inc wrote:
However, I find reporting of errors occurring within expanded postpone macroblocks a bit misleading (...)
Yes, it currently reports the last line of source (whatever it is) as the one that called the macro. I could probably improve it by creating internally an additional synthetic line that would be referenced instead, and this synthetic line would be ignored and not displayed by the error reporter.
But for now I settled with this perhaps a bit strange reporting, in order to avoid disrupting listing generators and other similar tools that may not be ready to handle such addition to .fas format.
Post 25 Oct 2013, 20:00
View user's profile Send private message Visit poster's website Reply with quote
shutdownall



Joined: 02 Apr 2010
Posts: 517
Location: Munich
shutdownall 25 Oct 2013, 20:24
Not sure - but maybe an idea.
Does this solution allow forward referencing of load/store directive ?
As it is executed at the very end of assembling ?

Only guessing ... Cool


For details - see my posting here:
http://board.flatassembler.net/topic.php?p=161504#161504

Hmmm maybe not as it is a preprocessor statement ... Sad


Last edited by shutdownall on 25 Oct 2013, 21:24; edited 1 time in total
Post 25 Oct 2013, 20:24
View user's profile Send private message Send e-mail Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 25 Oct 2013, 21:17
Very interesting new feature! It really makes some things more simple!
How about the serializing. What if there are several postpone definitions? Is it possible to call the previous from the next?
Post 25 Oct 2013, 21:17
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 26 Oct 2013, 12:28
Some bug detected in v1.71.14.
When compiling some on my sources, the compiler crashes on the instruction:
Code:
        rep     movs byte [edi],[esi]
      after_macro_operators:
    
ECX has too big and obviously wrong value. It crashes only on big sources. On small samples everything is OK. The bug is tested on FASMW and Fresh IDE under Linux/Wine.
Post 26 Oct 2013, 12:28
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 26 Oct 2013, 12:44
This does not tell me much. Can you prepare some artificial sample to reproduce the bug?
Post 26 Oct 2013, 12:44
View user's profile Send private message Visit poster's website Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 26 Oct 2013, 13:32
Tomasz Grysztar wrote:
This does not tell me much. Can you prepare some artificial sample to reproduce the bug?

Here it is. I tried to reduce the size, but I am afraid it is pretty big. Compile the file "TestLib.asm" in the directory. The environment variable %TargetOS% have to be set to Win32 or Linux, and %lib% to the "crash_14" directory. It compiles with 1.71.13, but crashes 1.71.14.


Description: Crash test example.
Download
Filename: crash_14.zip
Filesize: 349.88 KB
Downloaded: 548 Time(s)


_________________
Tox ID: 48C0321ADDB2FE5F644BB5E3D58B0D58C35E5BCBC81D7CD333633FEDF1047914A534256478D9
Post 26 Oct 2013, 13:32
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 26 Oct 2013, 15:37
Thank you. I did look at the right place earlier but I failed to notice that it was the right suspicion. Smile Please try 1.71.15.
Post 26 Oct 2013, 15:37
View user's profile Send private message Visit poster's website Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 26 Oct 2013, 15:47
Now it works fine. Thanks!
Post 26 Oct 2013, 15:47
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 26 Oct 2013, 15:51
Tomasz Grysztar
Quote:
Fixed some bugs inadvertently introduced in the previous release.

The bold "t" is missing. Smile

_________________
Faith is a superposition of knowledge and fallacy
Post 26 Oct 2013, 15:51
View user's profile Send private message Reply with quote
uart777



Joined: 17 Jan 2012
Posts: 369
uart777 29 Oct 2013, 22:43
Thanks, Tomasz.
Quote:
Using it for code definitely IS crazy. Smile
Smile Why is it considered "normal" to write/use macros for data but "crazy" to use them for code/runtime when they are most useful? Not expecting an answer.
Post 29 Oct 2013, 22:43
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1178
Location: Unknown
HaHaAnonymous 29 Oct 2013, 22:50
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 19:14; edited 1 time in total
Post 29 Oct 2013, 22:50
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 30 Oct 2013, 18:56
For macros it isn't but in the particular case of postpone directive it has an additional side effect of relocating to the end of the assembled output, which can be problematic for data or code*. Data is a little more resilient to relocation [still have to be careful!] but a change in a code path would have to be carried through or accounted for which makes things far more complicated - at least this was my view from playing around with it in the examples I showed.


*Here I'm considering the postpone { db 0 } or postpone { not eax } type cases that add more output; in-place side effects are not a problem and are the ideal use case.
Post 30 Oct 2013, 18:56
View user's profile Send private message Reply with quote
r22



Joined: 27 Dec 2004
Posts: 805
r22 01 Nov 2013, 18:57
Seems like you could use this to create optimized SWITCH...CASE jumptables. Based on all of the CASEs you could either create a flat LUT if the cases are normal (0 to N-1), or you could generate a table that requires binary search if the CASEs were sparse, or may a hash table.

Someone should really get to reinventing that wheel.
Post 01 Nov 2013, 18:57
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< 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.