Hello all, I am wondering if anyone wanted to discuss their personal coding style
using FASM's (really good) pre-processor capabilities.

I'm curious how many people use virtual & struc. Have any of you ome up with
interesting methods that help clean up code or make it easier to manage? How
many of you have taken advantage of FASM's large multipass capability?

I _already_ know how they work, I would just like to learn how others use them in
their coding regime. I'm sure we all have our own unique coding style, and this isn't
meant to start a war over which way is best.

For example:

Since I switched to FASM I was able to start coding my operating system using only
one file. Mainly do to the ability of FASM's org directive to be used "intelligently." This
has a number of advantages. I'm now able to avoid using makefiles and cumbersome
directory hierarchies. This lets me save a lot of time when I need to reorganize code.

I haven't started using virtual/struc too much yet, but will probably get into them a
good deal.

For the possible comment or forty-two on how style doesn't matter...
Legibility is a big issue not only for others reading your source but for you as well.
The line-by-line iterative programming style of assembly language is a main reason I
use asm to do all my coding. I found myself spending 50% of my time reorganizing HLL
code instead of actually programming it. (There goes the 80/20 theory!)

Keep up the assembling!
Posted on 2002-11-14 08:24:07 by jwm
OK, let's make this thread active, because it's interesting theme.

So, I am strange bird: Assembler and Pascal programmer. I never write on C and I don't like C. As Pascal programmer, I prefere to use clear data definitions and clear structured data and programs at all.

Began to use fasm, I try to use (and I am using) "struc" constructions very offen (more than "macro" constructions, because I don't like macroses very much, I think they makes source very unreadable. But struct is another deal. Using struct I can make my data very structured and readable almost like Pascal code and it's good. :)

But in fasm, sometimes, my noble intentions conflict with some syntax constructions. For example:

Using standard include files, appended to the fasm package, all structures are defined without data (using only rd, rw etc. constructions). This means, that if I use them, I must write program to fill actual data in the data structures. But WHY??? I must write following if I need only one constant data structure (This case is very common in Win32 programming):

section '.data' data readable writeable
section '.code' code readable executable
mov ,eax
mov ,0
mov ,WindowProc
mov ,0
mov ,0

It's a very bad method to make static data. I think and I began to make some structures with parameters, because to make them self defineable in compile time.


struc TPoint x,y {
.X dd x
.Y dd y
.Size = $ - .X

virtual at 0
TPoint TPoint ?,?
end virtual

Point1 TPoint 10,10
Point2 TPoint 20,20
Point3 TPoint 30,40
Point4 TPoint 0,0

So, how I use this in program. Let's we have some pointer to the array of points. And lets loop through this array and call some subroutine on every point. Array ends with Point 0,0

mov esi,Point1
mov eax,
or eax,
jz .EndLoop

call WorkOnPoint ; is pointer to the TPoint structure

add esi,TPoint.Size
jmp .arrloop


This is simple. But how we can init more complex data structures:

struc TPoint X1,Y1 {
.X dd X1
.Y dd Y1

struc TRect ATopLeft, ABottomRight {
.TopLeft TPoint ATopLeft
.BottomRight TPoint ABottomRight

virtual at 0
TPoint TPoint 0,0
end virtual

virtual at 0
TRect TRect 0,0,0,0
end virtual

The above example not works at all! If we want to make it works we must use some "rd" form, and init data manualy with program code:

struc TPoint {
.X rd 1
.Y rd 1

struc TRect {
.TopLeft TPoint
.BottomRight TPoint

virtual at 0
TPoint TPoint
end virtual

virtual at 0
TRect TRect
end virtual

MyRect TRect

mov eax,123
mov ,eax
mov eax,234
mov ,eax
mov eax,345
mov ,eax

This works, but this needless code, (sometimes a hundreds lines) I think must be avoided.

This difficulty to use "struc" with parameters are related to the struc and macro parameter passing syntax in fasm. Some of my suggestions are here:

Posted on 2002-11-20 04:27:05 by JohnFound
Why not:

struc TPoint X1,Y1
{ .X dd X1
.Y dd Y1 }

struc TRect Top,Left, Bottom,Right
{ .TopLeft TPoint Top,Left
.BottomRight TPoint Bottom,Right }

virtual at 0
TPoint TPoint ?,?
end virtual

virtual at 0
TRect TRect ?,?,?,?
end virtual


BTW, I was also a Pascal programmer, I was learning assembly by writing assembly procedures for my Turbo Pascal programs, and when there started to be more assembly than Pascal code in my sources, I moved to TASM. And then (well, much later) I was trying to make my own compiler - I wanted something like C, but with simplier access to assembly (maybe something like C--, but my ideas were slightly different), it was never finished, but it was able to compile assembly language, so I renamed it to ASM32 and started to use it, because it had syntax I liked more than the TASM's (but it was based on the TASM's Ideal mode, with a little influence of NASM, but I was never using NASM, the realy versions of it were so terribly slow... but it had some nice syntax ideas), and no linking process was needed. Only raw binary output format was supported (handy only for .COM files), but I was also creating DOS32 executables, because I was using that extender for almost all my projects these days. But then I had made my own extender, based on the open-source PMODE, but heavily patched and extended by me, and I was back using TASM, because my ASM32 was too slow, buggy and incompatible for such big projects. When my extender came to version 2.0, it had support for my own format of executables (using the flat memory model), and it started to be too complicated to use TASM for this purpose, I was also trying to write my own OS, and it was terrible to do it with TASM (I hated "db"-built instructions). So I decided to write an assembler once again, and this time (having an experience from writing ASM32) do it good. And so the fasm was born, first version also with flat binary output only, but it was simple to create headers and code for my executable format in this mode; also first version of fasm was in this format, running under my extender. And I had implemented almost all what I wanted - the clean syntax with all rare syntax options for the OS/extender writing purposes, and also simple TASM-Ideal-like macroinstruction system, with the exception that I decided it's simplier to search for the "}" character than for the "ENDM" word, but it was not because of my sympathy to C (in fact, I don't like C), but because round and square brackets were already reserved for other purposes.
And when I finally decided to release fasm officially (about six months later), I removed the extender (because it was big, slow, and buggy) and changed the code to work in flat real mode (it's also flat memory model, so it was no problem). And released it as the 0.9.x series on the FreeDOS project pages (and it's still one of the FreeDOS projects today), then in 1.0 introduced ability to format the output (the new additional format was MZ), and then in 1.04 added PE support and Win32 version and... it was growing and growing. I see I have written much more that I wanted, and a little off-topic, forgive me, that's enough.
Posted on 2002-11-20 05:31:26 by Tomasz Grysztar
Thanks for a really good reply. I was beginning to think noone cared about coding style. :(

When I used the struc {} I'd not initialize the data.

I'd do:

db 'Hello'

mov bx, .data.msg

mov bx, my_code1.data.msg

The above just kept data away from my code and let me put it at another place in the file. I'm sure there are a lot of other uses one could find.

I look forward to dropping IA32 on its head and moving on to IA64/Itanium. it's going to be a little expensive but for my projects that I do I think it will be very beneficial. Just thinking about programming in assembly with EPIC and many many general purpose registers gets my mouth watering. The best of RISC & CISC with the good of explicit CPU parallelization. ASM hackers dream! Compilers eat your heart out!

Btw, is John Found a play on John Fine?
Posted on 2002-11-20 05:45:54 by jwm
Hi Privalov!

About your example:

Yes, I know that this is one way to make this in my example with Points and rectangles. And this is way to make this in all complex structures. But imagine the structure with 3 or 4 levels of struc definitions:

struc S1 {

struc S2 {
.s11 S1
.s12 S1

struc S3 {
.s21 S2
.s22 S2
.s13 S1

struc S4 {
.s31 S3
.s14 S1
.s23 S2
.s32 S3

and now imagine all these parameters in one row separated with commas. This (IMHO) is very very unreadable. In other words, I think that fasm need some structured method of parameter passing. With brackets or with names. Note that every of this methods is optional, if I want, I will write:

MyStr MyStruc 1,2,3,4,5,6


MyStr Mystruc (1,2), (3,(4,5)), 6

That is all.

P.S. BTW I don't think that brackets "{}" is diference between C and Pascal. :)
Actually I think FASM is more "Pascal like" than C. And this is the reason I like it.

Posted on 2002-11-20 06:35:43 by JohnFound
Maybe some other idea I had from the beginning of fasm project (but never implemented it) would be useful for such purpose. This is the idea of specifying the separators for arguments for macro, like in the following example (each example macro finally produce the same code)


macro mv arg1,arg2
{ mv arg1,arg2 }

mv al,1

macro mv arg1 arg2
{ mv arg1,arg2 }

mv al 1

macro mv arg1->arg2
{ mv arg2,arg1 }

mv 1 -> al

macro mv (arg1=arg2)
{ mv arg1,arg2 }

mv (al=1)

As I said, this is the idea I had when I was designing the macroinstructions system for fasm, but it has never got implemented, maybe in future... (some version 2.0?)
Posted on 2002-11-20 06:49:38 by Tomasz Grysztar
Hi Privalov, you wrote:
I see I have written much more that I wanted, and a little off-topic, forgive me, that's enough.
Nope, very interesting reading instead. :alright:
Posted on 2002-11-20 06:50:29 by Maverick