flat assembler
Message board for the users of flat assembler.
Index
> Macroinstructions > advanced struct for fasmg |
Author |
|
zhak 10 Apr 2017, 23:52
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.
|
|||||||||||
10 Apr 2017, 23:52 |
|
Tomasz Grysztar 11 Apr 2017, 18:18
This is very interesting. I did not expect development of "struct" in this direction.
|
|||
11 Apr 2017, 18:18 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.