News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

How to handle the equivalent of C++ new statement

Started by lonewolff, March 05, 2009, 09:56:50 AM

Previous topic - Next topic

lonewolff

Hi there,

I am looking at trying to make a 3D application using the Ogre3D API (www.ogre3d.org)
With Ogre (in C++) the first thing that you need to do is create a 'new' instance of root. Like so;

Root *mRoot=new Root("","","app.log");

Is there any way that I can achieve something similar in asm? As I would not know where to start with doing this.  :red

The reason I would like to go with Ogre and not directX at this stage (dont get me wrong I love programming with DX) is that I can create a full 3D scene in around 20-30 lines of code with Ogre.
There is alot more setting up and work to do with DX and at this time I am just learning assembly (and getting pretty fast results too)

Thanks in advance.

xmetal

If your "client" code is responsible for both the allocation and deallocation of memory (i.e. for each "new" object that it creates, it also "deletes" it), then you can use any set of memory management routines.

Otherwise, you could create "wrappers" around the new and delete operators, which allocate opaque bytes, and which you call from your assembly routines. Or overload the new and delete operators, and call them instead.

Either way, it is your responsibility to call the constructors and destructors.

lonewolff

Yes.

But, where does someone begin to do this in assembly? Is there any tutorials around that explain how this is done?

askm

Hey all you assembler action figures out there thats the question.

Im no computer science investigator but is the c++ 'new' constructor

nothing more than allocating a memory space for it, and as such

implemented in a classy (class methods) way.

jj2007

Quote from: lonewolff on March 05, 2009, 08:24:59 PM
Yes.

But, where does someone begin to do this in assembly? Is there any tutorials around that explain how this is done?

Assembler is a low level language. It knows nothing about "new" "objects". However, nothing stops you to insert...
print "Start"
Root *mRoot=new Root("","","app.log")
print "End"

... compile it, then load it into OllyDbg and see how that effectively translates into movs, incs and invokes. Reverse Engineering is a no-no in this forum, but I think finding out how to translate a C++ "new" into Assembler is a valid exception  :wink

lonewolff

Surely it is ok to reverse engineer your own code though.

lonewolff

I guess the more relevant question is, what does 'new' actually do behind the scenes?

jj2007

Quote from: lonewolff on March 06, 2009, 10:03:08 AM
I guess the more relevant question is, what does 'new' actually do behind the scenes?

Find out. Put some easily identifiable statements before and after, such as...
a=12345h
Root *mRoot=new Root("","","app.log")
b=54321h
... and check in the debugger or disassembler what happens between these statements. The disassembler, as the name says, provides you with assembler code. Isn't that what you want? :bg

Mark Jones

Well in all fairness JJ, the output probably jumps all over the place. Chances are pretty good that the compiler isn't going to produce one nice, congruent block of code between those labels, no... it is going to create data structures and place a few calls to nested subroutines, which check everything from argument length to version of run-time libraries available... (OK maybe I am partially joking here, but the output may not be quite as nice and simple as one would like.)
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

donkey

#9
Hi lonewolf,

The new directive is not a mystery unavailable to ASM, it simply allocates memory on the heap using a structure template and passes the pointer as an HRESULT. So you might try this

Root *mRoot=new Root("","","app.log")

Root STRUCT
member1 DB SOMESIZE DUP (?)
member2 DB SOMESIZE DUP (?)
member3 DB SOMESIZE DUP (?)
Root ENDS

Since I don't know anything about the structure you will have to set the proper sizes and member names yourself, you should find these in a header file somewhere.

invoke GetProcessHeap
invoke HeapAlloc,eax,HEAP_ZERO_MEMORY,SIZEOF Root
mov mRoot,eax

at this point you have only to fill in the values with the strings in the parenthesis, lstrcpyn will do that nicely.

Edgar

edit - forgot to put in DUP :)
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

jj2007

Quote from: Mark Jones on March 06, 2009, 03:05:57 PM
Well in all fairness JJ, the output probably jumps all over the place. Chances are pretty good that the compiler isn't going to produce one nice, congruent block of code between those labels, no... it is going to create data structures and place a few calls to nested subroutines, which check everything from argument length to version of run-time libraries available... (OK maybe I am partially joking here, but the output may not be quite as nice and simple as one would like.)

Yeah, you are right, but that's the fun. Lonewolf is eager to prove that assembler is nice and simple, and confused compiler output is exactly the right thing to prove he is right :bg

lonewolff

Quote from: jj2007 on March 06, 2009, 04:08:28 PM
Lonewolf is eager to prove that assembler is nice and simple...

I dont recall saying that.  :bdg

I just want to see if I can understand what is going on and possibly ditch C++ altogether

...and maybe prove that you can make an MMO with assembly, with no budget, and a crew of one.   :bdg

tenkey

The WHAT is very simple...new will simply allocate storage, call an initialization routine, and return the object's address.

The devil is in the details. A chain of initialization calls can be produced if there are several classes involved, both as base classes and as object classes of member data. The initialization includes attaching tables of virtual function addresses to the created objects.

A lot depends on how much of the class hierarchy will be mimicked. If you need to have existing C++ code work with your object, then you need to follow all of the conventions for coding, data structuring, and "name mangling".
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8

jj2007

If I had a C++ compiler and strange-looking {brackets} on my keyboard, I would just compile the dummy prog (a=12345h, Root *mRoot=new Root("","","app.log"), b=54321h), drag it over good ol' Olly, find the 12345 and 54321, and post the stuff in between here in order to enhance the quality of life of those who are watching this esoteric thread :green

xanatose

new basically does 3 things

1. Allocates memory from the heap. If it fails, it throws an out of memory exception.
2. If the allocation succeeded it calls a constructor function depending on the class and parameters.
3. If am exception was thrown in the constructor, it frees the allocated memory and throws back the exception.

The first one is easy to do. Just call HeapAlloc and throw an exception if the result is 0. (or use HEAP_GENERATE_EXCEPTIONS flag)

The second one is more difficult as it depends on the compiler to know what function to call for the constructor.