flat assembler
Message board for the users of flat assembler.

flat assembler > Macroinstructions > advanced struct for fasmg

Author
Thread Post new topic Reply to topic
zhak



Joined: 12 Apr 2005
Posts: 489
Location: Belarus
Long story short, I finally created advanced struct macro for fasm g, based on and inspired by Tomasz's example, which can do some cool things. Would be glad if you could test it away and point to any bugs or suggest optimizations.

Before I start describing the macro, I'd like to say my thanks to Tomasz for this wonderful engine. When I first tried it when it first appeared I was like yeah, okay, its interesting. But it took some time and learning effort to realize how extremely cool it is.

In its current implementation the macro may not work correctly with pe.inc from examples if relocations are present in output .exe. This is because I redefine standard data types like dd or dword and align macro. I myself don't use pe.inc from examples and at the moment didn't have enough time to test against it. Sorry. I'll tune this later, when come back from vacation (having a flight in the morning).

datatypes
Code:
macro datatypes types& irp <size, type>, types @datatype.type equ ::type:: sizeof.type = size macro type args:?& match [value], args local count count = +value emit size: count dup ? else emit size: args end match end macro struc (__name__) type args:?& label .: size type args __name__.__size = size __name__.__length = $ - . end struc end irp end macro datatypes \ 1,db?, 2,dw?, 4,dd?, 6,dp?, 8,dq?, 10,dt?, 16,ddq?, 32,dqq?, 64,ddqq? datatypes \ 1,byte?, 2,word?, 4,dword?, 6,fword?, 8,qword?, 10,tbyte?,\ 16,dqword?, 16,oword?, 32,qqword?, 32,yword?, 64,dqqword?, 64,zword? macro datatypes_reservable types& irp <size, type>, types @datatype.type equ ::type:: sizeof.type = size macro type value* local count count = +value emit size: count dup ? end macro struc (__name__) type value* label .: size type value __name__.__size = size __name__.__length = $ - . end struc end irp end macro datatypes_reservable \ 1,rb?, 2,rw?, 4,rd?, 6,rp?, 8,rq?, 10,rt?, 16,rdq?, 32,rqq?, 64,rdqq?

The above macros add some fields to standard data types, so that it's possible to use sizeof.db to get data type size (in bytes). For named variables it adds inner properties:

    __size - data size
    __length - length of initialized data

Example:
Code:
lipsum db 'Lorem ipsum' lipsum.__size = 1 lipsum.__length = 11

It also adds the possibility to reserve data using the following syntax:
Code:
db [3]; the same as rb 3 or db 3 dup ?

The latter has been added just to introduce consistent look and feel for definition of structures and primitive data types

struct
simple structure

Code:
struct POINT x dd ? y rd 1 end struct point POINT x:1, y:2


structure in structure
Code:
struct LINE StartPoint POINT EndPoint POINT end struct line LINE StartPoint.x:1, StartPoint.y:2, EndPoint.x:5, EndPoint.y:6


arrays of primitives
Code:
struct LIST letters rb 4 end struct ; it's possible to fill the array with values list1 LIST letters:<1,2,3,4> ; or it's possible to override data types to fill more array elements at once list2 LIST letters:<word 0x1111, word 0x2222> list3 LIST letters:<dword 0x44444444> ; it's also possible to use smaller datatypes to initialize the variable ; but in this case the value will be padded with zeroes to data type size point2 POINT x:<word 0x5555> ; point2 POINT x:<word 0x5555, word 0x6666> is not allowed ; it's possible to address any item in the array separately list4 LIST letters[0]: 'a', letters[1]: 'b', letters[2]: 'c' ; data type can be overriden, too list5 LIST letters[2]: <word 0x7777>


arrays of structures
The same rules apply to variables which define structures
Code:
struct TWO_LINES lines LINE [2] end struct my_lines TWO_LINES lines[1].StartPoint.x: 1, lines[1].EndPoint.y: 5


Length of array can be obtained with __length property:
Code:
my_lines.lines.__length

It is also possible to initialize array of structures.
In this case index of the structure should be added as .[index]
Code:
other_points POINT [2] .[0].x: 1, .[1].y:2

Finally, it's possible to initialize zero-length arrays. This could be useful when the last parameter in the structure has variable length. In this case only parameter name is created.
Code:
struct POINTS points_count db ? points POINT [0] end struct

If zero-length parameter is a structure, then it won't be possible to address that structure's params directly. In this case parameters can be addressed in way like
Code:
mypoints POINTS mov eax, [mypoints.points + POINT.y + sizeof.POINT * INDEX]

Seems like that's most of it. Hope I didn't forget anything. Anyway, if forgot, then will add later.


Description:
Download
Filename: test.asm
Filesize: 9.22 KB
Downloaded: 131 Time(s)

Post 10 Apr 2017, 23:52
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6876
Location: Kraków, Poland
This is very interesting. I did not expect development of "struct" in this direction.
Post 11 Apr 2017, 18:18
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:  


< 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 © 2004-2018, Tomasz Grysztar.

Powered by rwasa.