flat assembler
Message board for the users of flat assembler.

Index > Windows > The new macroinstructions for Win32 programming

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



Joined: 16 Jun 2003
Posts: 7736
Location: Kraków, Poland
Tomasz Grysztar
After extending the features of preprocessor in latest fasm releases I have redesigned some of the macros for Win32 programming and created the new includes. The syntax for some constructions has been changed to be more TASM-like (but fasm-specific macros like resource, import and export creation are left intact). The "struct" macro uses now the syntax like:
Code:
struct POINT
  x dd ?
  y dd ?
ends

point1 POINT 10,10

struct LINE
  start POINT
  end   POINT
ends

line1 LINE <0,0>,<100,100>    

also support for unions inside the structures has been added:
Code:
struct FOO
 field_1 dd ?
 union
  field_2  dd ?
  field_2b db ?
 ends
ends    

The "sizeof" is defined for the structure and for the each field, so the above defines the "sizeof.FOO", "sizeof.field_1", "sizeof.field_2" etc. and also the absolute offsets for fields called like "FOO.field_1".

The procedures are defined with new macros like:
Code:
proc foo arg1,arg2

  locals
    var dw ?
    pt POINT
  endl

        mov     eax,[arg1]
        mov     [var],ax
        mov     eax,[arg2]
        mov     [pt.x],eax

        ret

endp    

but it can be done also this way:
Code:
proc foo2 arg1:DWORD,arg2:DWORD

  local var:WORD,pt:POINT

        mov     eax,[arg1]
        mov     [var],ax
        mov     eax,[arg2]
        mov     [pt.x],eax

        ret

endp    

The scope of arguments and local variables is local to each procedure and their names don't have to start with dot - but they also don't affect the NASM-like local labels mechanism, so if you define ".a" label somewhere inside the above procedure, it will be defined as "foo2.a".

You can define multiple "locals" blocks anywhere inside the procedure, the only restriction is that you have to declare the local before you access it.


Last edited by Tomasz Grysztar on 06 Jul 2005, 20:23; edited 7 times in total
Post 13 Jun 2005, 14:51
View user's profile Send private message Visit poster's website Reply with quote
decard



Joined: 11 Sep 2003
Posts: 1092
Location: Poland
decard
Great work! Nice that new proc macro allow to put a dot before argument name, as in Fresh sources Wink
Post 13 Jun 2005, 15:12
View user's profile Send private message Visit poster's website Reply with quote
decard



Joined: 11 Sep 2003
Posts: 1092
Location: Poland
decard
Hre's my SysTray example, with updated macros.
Post 13 Jun 2005, 16:58
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7736
Location: Kraków, Poland
Tomasz Grysztar
Also, there's a small MASM.INC file which simulates the MASM's syntax for "struct" and "proc" definitions. A sample program:
Code:
include 'win32ax.inc'
include 'macro\masm.inc'

.data

  _title db 'Win32 program template',0
  _class db 'FASMWIN32',0

  wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class

  msg MSG

.code

WindowProc proc hwnd:DWORD,wmsg:DWORD,wparam:DWORD,lparam:DWORD
        push    ebx esi edi
  .if [wmsg]=WM_DESTROY
        invoke  PostQuitMessage,0
        xor     eax,eax
  .else
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
  .endif
        pop     edi esi ebx
        ret
WindowProc endp

Start:
        invoke  GetModuleHandle,0
        mov     [wc.hInstance],eax
        invoke  LoadIcon,0,IDI_APPLICATION
        mov     [wc.hIcon],eax
        invoke  LoadCursor,0,IDC_ARROW
        mov     [wc.hCursor],eax
        invoke  RegisterClass,wc

        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,192,192,NULL,NULL,[wc.hInstance],NULL

  msg_loop:
        invoke  GetMessage,msg,NULL,0,0
        or      eax,eax
        jz      end_loop
        invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
        jmp     msg_loop

  end_loop:
        invoke  ExitProcess,[msg.wParam]

.end Start    
Post 13 Jun 2005, 17:04
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7736
Location: Kraków, Poland
Tomasz Grysztar
I have updated the package with further extended the capabilities of "struct" macros - they now allow union and substructures nestable with no limits, for example:
Code:
struct LINE
  union
    start POINT
    struct
      x1  dd ?
      y1  dd ?
    ends
  ends
  union
    end   POINT
    struct
      x2  dd ?
      y2  dd ?
    ends
  ends
ends    

When initializing the values by placing the as parameters to structure, the unions and substructures are treated as single fields. For example:
Code:
struct FOO
  a dd ?
  struct
    b dd ?
    c dd ?
  ends
ends

my FOO 1,<2,3>    

The second parameter initializes the substructure, its subparameters initialize the "b" and "c" consecutively.
When initializing the union, the parameter given to union is passed as the value to the first field of union (if some of the other fields is larger than the first one, there are undefined bytes placed to pad it to the size of union; the default values for the fields other than first are used only to determine their size). So this:
Code:
struct BAR
  a dd ?
  union
    b dq ?
    struct
      b_low  dd ?
      b_high dd ?
    ends
  ends
ends

foo BAR 1,2    

initializes the "b" quadword with value 2.

Any default values can be specified in the definition, like:
Code:
struct COMPOSITE
 first  FOO 1,<2,3>
 second BAR 1,2
 third  dd  1
ends    
Post 16 Jun 2005, 09:30
View user's profile Send private message Visit poster's website Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt
I'm having a problem converting my code. When do you use the 'enter' and 'return' macros? also, can you still use multiple 'returns' in the proc\endp macros?
MadMatt
Post 16 Jun 2005, 17:54
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7736
Location: Kraków, Poland
Tomasz Grysztar
You use the "ret" instead of "return" now, the "enter" is not needed at all, for defining locals see the examples in first post above.

If you want to assemble some code using old syntax for proc without converting it, you can try to use some wrappers over the new syntax:
Code:
macro proc name,[arg]
{ common proc name arg
  locals }

macro enter { endl }

macro return { ret }    


The locals and returns can be placed anywhere inside the proc in any amount - the only limitation is that declaration of a local must come before you use it.
Post 16 Jun 2005, 19:45
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7736
Location: Kraków, Poland
Tomasz Grysztar
I have extended the "struct" macro again, to allow the simple inheritance of structures (with TASM-like syntax). Simple sample:
Code:
struct POINT3D POINT
 z dd ?
ends    

defines the structure with x, y and z fields.

I'm attaching the extended include.


Description:
Download
Filename: STRUCT.INC
Filesize: 6.17 KB
Downloaded: 220 Time(s)



Last edited by Tomasz Grysztar on 16 Jun 2005, 23:13; edited 3 times in total
Post 16 Jun 2005, 20:29
View user's profile Send private message Visit poster's website Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt
Thanks Privalov! the macro changes look very promising! Very Happy (But, are going to require huge changes to all of my extra includes and code examples !WHEW! Crying or Very sad)
Post 16 Jun 2005, 21:57
View user's profile Send private message Reply with quote
Sem



Joined: 05 Mar 2005
Posts: 8
Sem
A little question:
Code:
proc Start
 xor eax,eax
 ret
endp
    

why in code:
Code:
push ebp
mov ebp,esp
xor eax,eax
leave
ret
    

what here proc prolog and epilog for?
Would be supported enter and return macros?
Post 23 Jun 2005, 08:27
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7736
Location: Kraków, Poland
Tomasz Grysztar
I thought it would be better to unify this, so if you depended on the fact that [EBP+4] contains the return address, it would be true for all procedures. I can correct it if you need better optimization for such procedures, though to write procedure without any arguments or local variables the "proc" macro is in fact not necessary at all.
For "enter" and "return" see above. You can use the wrappers to compile some old sources, but they are not officially supported now.
Post 23 Jun 2005, 09:44
View user's profile Send private message Visit poster's website Reply with quote
Vasilev Vjacheslav



Joined: 11 Aug 2004
Posts: 392
Vasilev Vjacheslav
hm, i think something like this will be very useful in fasm

Quote:

OPTION PROLOGUE: NONE
OPTION EPILOGUE: NONE
Post 24 Jun 2005, 09:29
View user's profile Send private message Reply with quote
shoorick



Joined: 25 Feb 2005
Posts: 1606
Location: Ukraine
shoorick
i like exactly current macro definitions.
in real:
if i create simple procedure, i do not use proc/endp at all
if i create large procedure - there is no sence to optimize it with skipping creating stack frame: if you have stack vars/params to access them via esp will cost much expensive then via ebp
Post 25 Jun 2005, 09:21
View user's profile Send private message Visit poster's website Reply with quote
shoorick



Joined: 25 Feb 2005
Posts: 1606
Location: Ukraine
shoorick
also in my rules are doing, then reading Very Happy so when i'd replaced fasm to 1.62 ver, i've been confused with my leave/ret 16 - i'd quikly solved this using retn intstead of ret Wink
Post 25 Jun 2005, 09:46
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7736
Location: Kraków, Poland
Tomasz Grysztar
One more MASM-like syntax feature added to "local" macro, it now allows to declare local array like this:
Code:
local var[100]:WORD    
Post 26 Jun 2005, 14:45
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
well, these macros are nice as example of FASM's preprocessor power, but i afraid people migrating from MASM will use them by default, which isn't very good. I think you shouldn't include them in standard set, just somewhere on board.
Post 26 Jun 2005, 18:58
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier
vid,

Quote:
people migrating from MASM will use them by default, which isn't very good.


Do you mean the code generated is not good, or do you think that there should not be any variation from "raw standard" FASM coding style? Either way, I disagree. Theses macro additions make the FASM much more attractive to a much wider user-base.

If there is reason why using the MASM-style macros is bad, I'd like to hear it.

I have enjoyed the old FASM, but enjoy the NEW FASM even more.

farrier

_________________
Some Assembly Required
It's a good day to code!
U.S.Constitution; Bill of Rights; Amendment 1:
... the right of the people peaceably to assemble, ...
The code is dark, and full of errors!
Post 26 Jun 2005, 19:57
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
reason is same like with many people using MASM after reading few tutorials or migrating from HLL - they don't understand what are they doing. For example many even don't know how the stack works, just because using "local" feature etc. Then they have hard-to-find bugs because of uninitialized variables or wrong usage of SS,SP,BP using pointers to local variables with different segment and many alike.
Post 27 Jun 2005, 07:38
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight
Mad i've wwritten only a few programs for Fasm but i have an unusual style pf programming (i ocasionally code my own function not using proc) anyway in one program i coded a function inside a proc the problem is that 1.62 inserts a leave before each ret inside a proc so my function inside procs end up leaving the proc before they are suposed to. is there any way i can fix this becasue it's very annoying.

Image i've fixed the probelm by using retn insted of ret to return from my manual coded function but i'm not really happy with using this method. i personally perfer the old method of using return to return from procs becasue that allows me to use the ret op code.Image
Post 27 Jun 2005, 11:22
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7736
Location: Kraków, Poland
Tomasz Grysztar
The RETN and RETF are the actual opcodes, the RET is the higher level instruction, defined by Intel to cover those both opcode types, depending on the context (the procedure where they are used). When there is no context, like outside the procedure, RET is equal to RETN in meaning, but when designing the new "proc" macro I preferred to follow the standard and make "ret" be automatically generated exit from procedure, like in TASM etc.
Post 27 Jun 2005, 13:43
View user's profile Send private message Visit poster's website 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-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.