There is too many things to say. A lot of works have been done by the pioneers. As soon as I touched the OOP stuff in asm, I was charmed. But as I using them, I found the syntax and usage isn't very covinent, there still are too many things to do by hand. So I started to imagine a new OOP model. To achieve this goal, I first analyse the design before, and reviewed the model used by C++ and object pascal. I have written a article dissecting OOP model made by Thomas and NaN, but the article was written in my mother tongue - chinese.

After this, I have made serval test and write about 200 line macro to test the macro capability of MASM. Result of the test was inspiring. I posted a post in the board to get advices. But I forgot one thing, that is searching. I searched the board today, and found many many useful things. Serval people have done great work on this, but I think further improvment is still needed, and is far from the final end.

Before any technic discussion, I want to have a introduction of myself. I am a student of Beijing Inistitue of technology. I love C++ and asm, but didn't code much. I hate code bloat and any unnecessary overhead. As you might know, My country and people is struggling with SARS, and there is no promise that I will be free from this terrible disease. My school have stopped the lesson and let us stay in the dorm, so I have enough time to have a fully insight on OOP and asm. I believe we will win the war against SARS, and I believe I will work out something useful when We back to the class.

What is OOP

Instead of teaching people that OOP is a type of design, and giving them design principles, people have taught that OOP is the use of a particular tool. We can write good or bad programs with any tool. Unless we teach people how to design, the languages matter very little.

- David Parnas

The first step of implmenting OOP is understanding what the OOP is. OOP is not C++ is not com is not C#... It is a methodology in programming. The accurate definition is hard to find and is not necessary here. I just want to resay three well known concept of OOP - encapsulation, polymorphic, inheritance. And some term used very often - public, private, override, overload, virtual, abstract base class, etc. I am not a expert or a professional in this field, as I wrote above, I am just a university student and my major is mathematics not computer science. Now, let's begin

Encapsulation is the first concept we should understand. When I saw OOP in the very first glance, I thought it is just put data and function into one "Object". After a long time and read serval wonderful book, I knew what the OOP really is , but the importance of encapsulation is still there. Encapsulation indeed put data and function together, and ADT is a term which always appear with encapsulation.

ADT stands for Abstract Data Type. Stack, linked list are very classical ADTs, and the very beginning purpose of C++ is support UDT, user defined type which is a little like ADT. They all use encapsulation internal. Object-based programming paradigm is also related to encapsulation.

OOP which based on object and more than Object-based uses encapsulation as the foundation, so how to implment encapsulation in asm or more accurate MASM is the first thing we should take into consideration. I just want to talk about term here, the possible implmention was not intended. The word "put" and "together" are the keys.

Field frequently used to refer data and method of a object together.The relationship between Class and Object should be explained first. Syntax and Keyword differ from languages. I just know the meaning of class, type, variable, object of C++. In C++, class refer to a UDT defined by user via keyword class. type refer to both UDT and native data type, so a class CPoint written by user or int float is a type. variable refer to the instance of built-in type more often, and object refer to UDT instance. Instance is word which is hard to explain, just a thing, a real thing.

Method is what the object can "do", take operation on the data member or external data. Member Function is also the same meaning in pratice. Message is another seldom used OOP term, which I thought means invoking a method.

Public & Private
Without Public and Private the encapsulation was not encapsulation any more. Pubic and Private was the keyword used by C++ and object pascal, I don't know if there is any language which use other word to represent similiar concept. Public and Private restrict the access. The user can only access Public field of a Object that is public data member and pulic method. Private field was designed for internal use, that is the method inside a class can access private data or method.

It is a impactful way to write reliable code. Another word "protected" always appear with this two words. Actually, if Object-based, pulic and private is enough to figure out the difference between fields, if Object-oriented, protected must be introduced to complete the sememic. I haven't considered how to implement protected in macro, so stop here.

Overload is technology which support serval function with the same "name", but not the same parameter. As Overload and Override both have polymorphic effect, so the two term often confuse someone. Overload seems to be magic that It allows you define serval function take the same name but invoking the function will be the right one you want.

The function can be a function in global scope or inside a class. If you know the dirty work hiding from you, you will know it is just a small trick. Name mangling is the trick, the function name was modified with added information, so the function with same name actually are different.

Inhertiance is another key concept of OOP. In the beginning, people think inhertiance will be a powerful tool to solve code re-use problem, however, to represent the relationship between class is the first place thing. There is public inheritance, private inheritance, protected inheritance.

The difference between the three inheritance is how to regard the Private, Public, Protected field of base class. Because I didn't have a complete idea of how to implment private, public, protected, further discussion is needed. Inheritance will let the derived class inherit the base class's data member and method, and if the method may be overrided.

Virtual method is a concept from C++, and many other language all method are virutal, such as java. Virtual method may be overrided by the derived class to do different thing. CShape may have a virtual method, and CCircle, CRectangle which inherit the CShape may override the virtual method to do different calculation on area.

Abstract Base Class
If a class have a virtual method wich have no implmention, and the derived "MUST" override the method, the class is a Abstract Base Class. You can let CShape be a Abstract Base Class. How to define a method which have no implmention is hard to say, In C++ is =0.

Many people told me that this concept is the essence of OOP, however, this is the source of OOP's time and space overhead. invoking a method via a ptr may have different behavior. In a more general definition, polymorphic includes a overload and many other useful stuff, but people refer polymorphic to virtual function more often. How to implement it is the most important part of OOP model, and I will discuss this in the next part in a detail. Things related to polyorphic needs a whole book, just one thing is the most basic, invoking a method via a ptr will invoke different method.

edit: I spaced it a bit for clarity and added some focus point. It was a long text and I hope this makes it easier to read.
Feel free to change anything you don't like of course, no content was changed. - Hiroshimator
Posted on 2003-04-25 22:35:54 by taowen2002

Thanks for telling us a little about you and where you are studying at the moment. I am very sorry to hear about the SARS problem in China but over time this problem will be defeated so I guess there is hope there.

Something I would suggest to you in your pursuit of designing OOP code is to get a very good grounding in the low level capacity in MASM so that you can implement new and interesting designs in the area of object oriented programming.

It is good that you have taken a low level approach to OOP rather than just using and existing package or high level language as it will get you underneath the assumptions and into the design of OOP code that can be far more efficient than some of the ordinary forms available.

You are already familiar with the OOP work of NaN and Thomas but it may be worth you also having a good look at the work done by Ernie Murphy as well because he did a lot of good quality low level work using the assumptions of assembler rather than a high level approach.

Regards and good luck with your research.

Posted on 2003-04-25 22:46:50 by hutch--
Thank you for your kind words, I and my classmates always have confidence!
I have had an insight look into the com stuff, and translated one of the articles into chinese. Even I have used a language E which was invented for writting code chinese to invoke a com method. Recently one of my friend give me a location :quantum-leap.com, in which there is a C+ includes. It use the macro capability supported by C to give a OOP extension to C.
Overall, I have known a lot possible OOP model, and I will first write serval article about them, and have a discussion about how to design this new OOP model. I Believe I can work it out!
Thank you, hutch, Your work on MASM is so great!
Posted on 2003-04-25 23:17:11 by taowen2002
Sounds great to me.. your explaining it better than i have to people. I look forward to seeing your ideas for a new model.

I *do* know that there is faults with our current model. To be honest, we never intended it to get as far as it did. The origional idea was to design a quick set of macro's to give better management of heap memory. Then with alot of collaboration between Thomas and I we turned it into what it is today.

The model was totaly 100% from our imaginations. We didnt peek into any C++ dissasemblies etc., so its in a way one mans take on it. It was a fun project. It fun when you discover how to do things on your own. I remember sitting on the back porch sun tanning in the summer when it hit me how to successfully "inherit" two of our objects together ;) . That really open the door for the model to expand.

I still dont even know if that is the best way of inheriting to be honest. But i do think a very serious model should be put together for low level assembly. Our OOP model works for small "quick and dirty" applications, but for large OOP based programs there is some visible inefficiencies in our model.

So again, i come back to where i started, I look forward to seeing your ideas ;)
Posted on 2003-04-26 17:42:10 by NaN
You are modest. Your design is quick, just a little overhead. non-virutal method can be supported just modifying your code 7 lines. I have done this in 5 mins. OVERRIDE may cause a entry be set 2 or more times.
I get down to what other people have done, and what is the most convinent way to express the syntax. The most difficult part is how to place a object inside a object, the parameters of the base's constructor and the member class's constructor are a big problem, I don't know how to express the thing which in C++ is init list.
I will write a aritcle analyse the way C++ use. I know serval people have tried OOP in asm, but I still want to have my try.

Thanks, Hiroshimator, It now looks more beautiful.:alright:

Thanks, NaN, I need your advices as I modeling my design.:alright:
Posted on 2003-04-26 19:02:00 by taowen2002
Object Model
Too many description of OOP is useless, we want to work out a macro solution to OOP object model. Thomas and NaN said they designed their model by themselves, influence from other languages was little. So, they didn't follow the C++'s way or Other language's way. But, a widely view on what other people do is meaningful and will be very helpful. The major reference I can get and I wish to refer is C++, object pascal, Thomas and NaN's macro, C+ , COM. One book which is so famous that can not be omited, "C++ object model", lipppman96. I will write something about them, but not in every detail, because I am just a amateur.

When people talking OOP, they always thought C++. C++ is too widely used that we have to have a insight look at it. Some features can be omited, such as operator overloading. A principle of Bjarne Stroustrup is no extra overhead should be introduced. As asm group, C++ group always talk about efficiency. So non-virtual method is supported, RTTI is limited...

Class contain both data and function. When we use C, we use FILE struct and fopen fclose to do work. In C++, the FILE struct and fopen fclose function can be a fields of a class. Set FILE be private, encapsulation was done. How to do this in the background? The simplest method is to put the data and the pointer to the member function into a structure, and every member function takes a pointer to the class's object which in C++ refers to this pointer. This method can be implmented very easily. But extra function pointer occupy the space and invoking the member function requires a redirection. So in C++, the non-virtual function is placed outside the class, just modify the name of the function to mark the relationship between function and class. All these stuff is hidden from the user, so you can thought the function was in the class, but actually you are just calling the function outside the class, just like fopen or fclose. data member was directly placed in the object.
virtual function is more complex, there is a vptr and vtbl. These words can also be seen in COM. In a simple design, It is nature to place the pointer to the virtual function into the structure directly, and the derived may using other value to reassign the pointer then OVERRIDE occured. But C++ use a table to contain function pointer, and just place the pointer to the table into the object. The pointer to table was known as vptr and the table itself was known as vtbl. Besides ptr to virtual function, RTTI info was also stored in the vtbl. The vptr may be set and reset in constructor, destructor and copy assignment operator.

Access section such as private or public were implmented by the complier to check every statement about the object. It just a thing about the type of symbol, mark the field to be private just have effect on complie time.

Static function or data is just function or data in the global scope with the name modeified. The funct or data will not be placed into the object as the non-virtual function do. So, they belongs to a class no a object. Static function do not have a parameter named this which point to the object who are invoking the function. So, static function can be used as call-back function in win32 programming.

Inline was a special keyword. It try to elminate the cost carried out by invoking a function. I think in asm, inline is not important, can be supported future, but not so necessary.

Object can be created either in the heap or in the stack. Local object is an important feature of OOP. Pointer to a object is an long-time problem in pratice. Local object will be constructed after defined, and be destructed immediately before the function exit its scope. HDC can be stored in CDC and the destroy can be carried out automaticly.

inheritance in C++ is just a structe contain its base sturct in normal case, but virtual base cause a more complex situation.

I intended to have a discussion about C++'s design, but now, I found it is too complex, and consume a lot of time, Stop here.

Object pascal, C+, or something other
Object pascal also have vptr and vtbl. But it built-in VMT, DMT and advanced RTTI support in the object model. DMT is very alike IDispatch in COM. Advanced RTTI will surely means nothing in asm.

C+ is a macro extension to C, due to the syntax supported by C, its funcionality was limited. But there is one thing interesting. In C++, access section was protected by the complier, how can this goal be achieved without the complier? C+ uses name mangling to do this, private member modify its name with a __, protected with a _. It makes a sense that What we can do to let our OOP model support private public protected.

I have also seen a odd implment in the board. A smart guy used a dll to represent a class. Although a lot of time and space was wasted, but a new idea indeed.
Support multi-inheritance or not is a big question. The diamond problem was hard to overcome. Effiel as one of the best OOP language have something interesting about this. But I didn't have time to have another insight look at this large thing. Maybe someone familiar with it can help me.

Many many other new language have a lot of things good. They are modern but they are more concern about the stuff about mordern commercial use. Pure and efficiency are always the major topic of ASM.

Discussion about other language is enough. Someone may have new idea or have something good to show me, Let me know! mal to :mo2mo@163.com. I will start to show my idea about how to design and what is the design of OOP model in asm. I just familiar with the macro usage of MASM, I know some other asm language also support powerful macro, if you know how to use them, you may send me a reference of it, I may rewrite all of my work in it.

Posted on 2003-04-26 20:27:47 by taowen2002
Originally posted by taowen2002
C+ is a macro extension to C, due to the syntax supported by C, its funcionality was limited. But there is one thing interesting. In C++, access section was protected by the complier, how can this goal be achieved without the complier? C+ uses name mangling to do this, private member modify its name with a __, protected with a _. It makes a sense that What we can do to let our OOP model support private public protected.


I raked my brain over this topic for a good while and never saw this very simple solution. I kept saying to myself.. Asm can't be private.. its ASM! it the true low level! I guess this thought clouded my judgement. I can easily see how to now make a class private with MASM. Simply write the METHOD statement to append the proper prefix to all calls, ie "public only please" ;)

I cant believe i never thought of that... doh! ;)

Posted on 2003-04-26 22:38:09 by NaN
Yeah, that is why I want to have so much seem-to-be-useless things first. Other people have done great on work and have great ideas.
Let me continue:
One possible design using macro in MASM

Now, I will talk about my idea about designing a OOP model in MASM. But please allow me to have another discussion about macro first. Many people who are familiar with asm may have known the power of macro, I have seen maro implmention of switch case and array, all of this should be the work of a complier. Macro allow us generate code before assemble. Some useful features are important in the following designing.

Macro with parameter
This feature of macro was widely known. In C, simple macro such as #define pi 3.14 was used to define constant, but macro with parameter ability was not used as often as the simple macro. In MASM, macro can take serval parameter, and the number of the param can be a variable. REQ let the param be a must, VARARG make the parameter number variable. Even default value can be given. Invoking a Macro was easy. Two forms are allowed. Four bulit-in macros were useful in string process.

Macro with return-val
A macro can have return-val let us divide one big macro to serval smaller macros. Sometimes, macro seems to be a function.

TEXTEQU, EQU, Name assignment
The three are significant tool to mark the symbol of OOP. TEXTEQU can be used to record infomation given in one macro, and the other macro may do something based on the value of TEXTEQU. Name assignment may be used to record the scope of the statement, EQU can be used to assign constant to a symbol. Overall, they are used to record information, to "pass" info between macros. One thing can not be omited, the textequ can be used on a string dynamic created, i.e. you can use other strings to form a new string and use TEXTEQU to let the new string to be some other string. You can see how powerful they are.

Macro with Conditional testing and Loop operators
It is easy to see the significance of FOR WHILE...

Condition Assembly, OPATTR
Condition Assembly was often used to test if a param was blank and used to test if two string are the same. OPATTR was used to test the existence of a symbol and the type of the parameter. All these are important.

may be used to create stack based object.

(to be continued)

I am not very clear about the TYPE SYSTEM of MASM, can anyone explain this to me? Thank you.
Posted on 2003-04-27 01:02:09 by taowen2002
Always good to see interest in ASM OOP.

The macro OOP framework I wrote was inspired by the great work Nan and Thomas did, after the positive response I got I decided to try something different and decided to write an OOP preprocessor for MASM. I hardest thing I found was defining a syntax that fit with MASM, did everything that was required, and didn't clutter the code or restrict the control ASM gives you.

I look forward to seeing a killer OOP design :alright:


It's always the easy things that avoid the mind. :grin:

I hope to release the preprocessor sometime this week, as long as it doesn't implode on me.
Posted on 2003-04-27 02:29:16 by Maelstrom
There is something difficult to design the syntax. I am trying, but no promise on the solution. The most difficult is on the constructor of member class and base class, and accessing object via pointer.

Can you talk something about your design? I didn't have enough time to look your work carefully.
Posted on 2003-04-27 05:21:39 by taowen2002
I've only played around with the two class structure formats below

This format stores both the data and virtual/abstract method pointers in the class structure.
Advantages are you can access all data and method pointers without the need to modify the THIS pointer and virtual call overhead is minimal.
Disadvantages are you use slightly more memory per object and virtual method pointers need to be initialized everytime you create an object.

; our class structure

_Destructor LPFUNCT1 ? ; must be first
_handle dd ?
_VirtualMethod LPFUNCT1 ?
CFILE ends

; assuming EBX points to our object

mov eax, (CFILE ptr [ebx])._handle

invoke (CFILE ptr [ebx])._VirtualMethod, ebx

This format stores the virtual/abstract method pointers in a VTBL and the class structure contains a pointer to this table.
Advantages are the object is quicker to initialize, the virtual method pointers only need to be initialized once, and memory is kept to a minimum.
Disadvantages are the increased overhead of virtual calls which generally results in the trashing of a register which means it can't be used as a function argument.

; our virtual method table structure

_Destructor LPFUNCT1 ? ; must be first
_VirtualMethod LPFUNCT1 ?

; our class structure

_vptr dd ?
_handle dd 0
CFILE ends

; assuming EBX points to our object

mov eax, (CFILE ptr [ebx]).handle

mov edx, [ebx] ; get vptr
invoke (CFILE_VTABLE ptr [edx])._VirtualMethod, ebx

Now what?
Constructing an object with no base is easy, but things can turn hairy fast with single inheritance, multiple inheritance, embedded objects, and templates.
How you handle this will depend on your class format and how far you can push MASM macros.

I'm no expert on OOP and these are only my opinions.

Keep fighting the good fight :alright:

Posted on 2003-04-27 08:17:16 by Maelstrom
Thank you for your explaination.

OOP model design
designing a OOP model is rather harder than I ever thought. There are so many things to be taken into consideration. Many people's work have given me a lot of good ideas, and many people have shown their opinion on this to me. I will first to give a code sample which possiblly could come true.


VAR Info :DWORD, 0



mov eax, Info
mov [edi].Info, eax

METHOD GetInfo VIA edi
mov eax, [edi].Info

METHOD ShwoInfo VIA edi
PrintText "In CBase"
PrintDec [edi].Info
CLASS CDerive : CBase


METHOD ShowInfo VIA edi
PrintText "In CDerive"
PrintDec [edi].Info

.model flat, stdcall
option casemap: none

include \masm32\include\debug.inc
includelib \masm32\lib\debug.lib

include objects.inc
include CBase.asm
include CDerive.asm

VAR pObj : PTR CDerive

NEW CDerive
mov pObj, eax
METHOD pObj, SetInfo, 1
CAST edi, pObj
METHOD edi, ShowInfo

TestOOP proc
VAR obj:CBase
METHOD obj, ShowInfo
TestOOP endp

end start

codes listed here are just a imagination. And many aspects were not covered, such as member objects. I will try to analyse it and give a solution.

Posted on 2003-04-27 23:06:00 by taowen2002
A previous snap just to show the complexity of the project
Posted on 2003-05-02 12:01:11 by taowen2002
taowen2002, very impressive work!

Might I suggest not using the .MODEL directive - replace it using the segment directives. This affords greater flexiblity in the log run. MASM maintains a stack of what segment is the current segment, and the placement of macros will become arbitrary (or even adding the ability to create static objects in the data section, dynamic objects in the code section). Between this and making adjustments in the link stage there is another layer of abstraction.

.MODEL flat, stdcall

can be replaced with:
; this would not even be needed if STDCALL was added to the API PROTOs


; Set Default Segment order and options:





There are many benifits to doing this, and the long term use of your macros will be better for it. I have explained on the board the reasons to do this: greater alignment granularity, code/data placement, code/data flexiblity, etc...
Posted on 2003-05-02 20:52:45 by bitRAKE
Thank you for your advices.
I want to use PROLOGUE to support stack based object, can you give me a example of this?
And some example of how to facility the advice above.

Thank you again.:alright:
Posted on 2003-05-03 05:20:48 by taowen2002

And some example of how to facility the advice above.
This thread shows problem using simple segment directives:

Important fix needed for segment switches in macros:

Ordering data in the executable with SEGMENT names:
Posted on 2003-05-03 10:27:34 by bitRAKE
I really appreciate your help
Posted on 2003-05-04 05:42:21 by taowen2002
There is only TASM support TABLE. Building VTable is the most important thing for OOP and it's a little harder to build by hand, that's why some asm OOP need preprocessor.
I've written a full TASM Object Model and I also wrote some macros to build VTable(a simulator of TABLE directive).
The macro is powerful enough to build true OOP, we don't need other preprocessor.
They are written in pure TASM Ideal mode, but it's easy to convent them to MASM mode.
btw, are you the Tao who post an article on asm OOP in CSDN?
Posted on 2003-05-06 22:55:38 by KomsBomb
Great work, I will look at it in detail.

Yes, that is me. We are CHINESE.
Posted on 2003-05-07 02:58:52 by taowen2002
A most recent snap-shot
Posted on 2003-05-21 10:04:32 by taowen2002