This text deals with a possible implementation of a oop framework in masm.
I assume you are familiar with oop and its terminology. The framework is not yet
completed, these are the first results of this implementation.

The whole idea is based on the power of masm macros and dlls (dynamic link libraries).
We will use a dll to represent our class. Dlls are used for our class
members initialisation and other class scope related data. Thus you may imagine
the pros and cons of using dlls
(if you are not familiar with dlls refer to the win programmers guide).

The description of how a dll must be coded in order to get it being initialised,
will be given at the end of the sample code.

To start, a sample code is demonstrated below (the explanation follows):

use Window ;we need to include class "Window"

class Frame extends Window ;multiple inheritance possible, seperate params by commas
;public data
make setTitle, dword, dword ;class methods
make getTitle, dword
positionX dword ? ;class member variables
positionY dword ?
;... other class members
Frame ends

.model flat, stdcall
.stack 0ffh
option casemap :none

include ..\include\Global.inc ;contains global macros

use Frame

title_frame byte "MyFrame", 0 ;title of our frame

frame dword ?

mov frame, new( Frame ) ;create new instance by calling macro "new"

eval Frame::frame.setTile, addr title_frame
eval Frame::frame.setSize, 100, 100
eval Frame::frame.setVisible, TRUE

;... some code
destruct String::string ;destroy our String instance
eval ExitProcess, 0
end start

The "use" macro
This macro simply includes data from another file, if suffix is omitted,
then it will append ".inc" to it.
In our case, "Window" just contains another class declaration declared by
the "class" macro discussed in the next section.

The "class" macro
This macro declares a new masm structure named after the first parameter given to it.
If the 'key' "extends" is found in parameter, a nested unnamed structure of the type
following the key is placed in this class.
Considering our class, the following structure is generated:

Frame struct
Window { }
Frame ends

If there is more than one class to be inherited, it will generate as many
nested structures, e.g.:

class Foo extends Bar, Baz
Foo ends

will become:

Foo struct
Bar { }
Baz { }
Foo ends

The "make" macro
"make" is used to declare a class method. Depending on its params, it will generate
the masm prototypes, so "invoke" can handle the invokation, i.e. it will be able to
do type checking.

make testFunct, dword, dword

will become:

??0001 typedef proto :dword, :dword
??0002 typedef ptr ??0001
testFunct ??0002 ?

Since "make" is a macro, we can use local vars, so they are named "??nnnn" (i think),
this guarantees that there will be unique prototypes created, and thus avoid name

The "new" macro
This macro might be the most important one. You call it when you want to have
a new instance being created.
The parameter must be a class name, optionally, you can give it some other params,
but they are ignored in the first version of this framework.

"new" will call the class constructor. If the class is a subtype, i.e.
it inherits some other classes, the constructors of that classes are called first
(the order of the class names passed to the "class" macro is essential).

mov frame, new( Frame )

will first call constructor of Window, then the constructor of Frame.
If Window is a subtype, too, the constructors of the inherited classes are called
recursively. So, there might be no problems of data initialisation.

The "eval" macro
Once you have created a new instance, you are able to call its methods
- "eval" is an extended "invoke", so you may call static procedures, i.e. procedures
defined in any .code segment.

- eval Frame::frame.setTitle, addr buf

This will call the method "setTitle" of the instance "frame" as a type of class "Frame".

- eval Frame::getCurrentFrames

If the class Frame has static functions, you may call it in this way.

- eval ExitProcess, 0

If no class name given, a local procedure, e.g. a procedure placed in .code
segment, will be called.

The "destroy" macro
That's obvious, isn't it? -- Will free any resources, in this case,
it will call the class destructor, then freeing memory.

How a class must be coded
As already said, we use dlls to wrap some objects. A dll (for our uses) must contain
certain procedures. These procedures must be called "construct" and "destruct", you
may define static class procedures as well.

Now, a sample:

.model flat, stdcall
.stack 0ffh
option casemap :none
option nokeyword :<this> ;we need keyword "this" for our purposes

__CLASS equ <Frame>

include ..\include\Global.asm

FrameEntry proc hInst:dword, reason:dword, reserved:dword
mov eax, TRUE

construct proc this:dword
setObj eax, this, Frame ;same as "assume eax:ptr Frame"
setMem setTitle, offset _setTitle ;will do "mov .setTitle, offset _setTitle"
setMem getTitle, offset _getTitle
;some other inits
construct endp

destrucct proc this:dword
destruct endp
;static function
getCurrentFrames proc
; our code
getCurrentFrames endp

_setTitle proc this:dword, title_frame:dword
;... our code
_setTitle endp

_getTitle proc this:dword
;... our code
_getTitle endp
end FrameEntry

You have to generate a dll, thus you need the exported label names.
In this case, we must generate a file consisting of

EXPORTS construct

That's all, i think. Now, there are some problems.
The framework is not finished yet, so it will take some more time to finish.

Already implemented:
- multiple inheritence
- polymorphism (not tested yet)
- some other stuff i cannot mention right now ;)

There is still to be done:
- constructor parameter support
- proper super class constructor calls (does not work properly)
- and some other things i have forgotten

So, if you think this might be a good idea, i will try to develop it and maybe
it will be finished as early as possible.
You may even want to help?

Posted on 2002-03-13 13:20:17 by exzito
I thought about something similar but it requires and conversion stage where it converts the non MASMs into MASM. At which point, it's easier to create a new assembler all together. Point 2 is that most asm programmers want absoulute control and don't want to bloat up source or binaries.

I would certainly use it but I don't know how much support you'll get from most of the community...

Posted on 2002-03-13 15:50:07 by _Shawn
Nan's OOP website (download page)

This is the site for downloading the OOP macros and examples associated with this type of programming... Credit goes to Thomas and Nan for their work in the area :)

Unless I'm mistaken this is what you were planning on doing...

As for support :)
The more tools the better... Never limit yourself...


To Nan or Thomas (if you read this)
Is there an update in the works?
Posted on 2002-03-13 16:13:54 by Sliver
If you're going to go DLLs for your class code, might as well make them COM classes so they can be reused most anywhere by most any language.


And to those doubting Thomases, OOP is a concept, it's not bloat. (MFC is bloat, you can do bloated OOP and you can do minimal OOP, your choice). OOP doesn't mean bloat, but I'm tired of making that argument over again and again.
Posted on 2002-03-14 00:53:10 by Ernie
I'm glad I caught it this time around :)

Do you give an good examples of some oop bloat vs non-bloat?
You can just point me to a thread (searching "oop" doesn't really work)

Posted on 2002-03-14 01:22:36 by Sliver