flat assembler
Message board for the users of flat assembler.
Index
> Main > Compiling OO code |
Author |
|
Tomasz Grysztar 13 Jan 2006, 12:54
One of the common solutions is to provide the "hidden" parameter to all the procedures declared as methods, which carries the pointer to object instance. This way you can have one common instance of the code, to access the variables of the object you use the pointer from hidden parameter, and when you call another method of the same object, you pass the same hidden parameter to it.
|
|||
13 Jan 2006, 12:54 |
|
Big Red 13 Jan 2006, 13:51
Quote: And I can't allocate memory for it on the stack since I can many objects at once and creating mysecondinstance will mess up the stack for myfirstinstance (I can access variables in myfirstinstance before destroying mysecondinstance). Or won't it? You just have to set up a stack frame via the ebp register. For example... SomeProc: push ebp mov ebp,esp sub esp,(sizeof total local data you want to use, in bytes) ... Here you can access your classes by indexing them with EBP. For example, if you have two local classes, and your classes follow the same size definition as STRUCT, you can write... mov eax,[ebp-sizeof.ATESTCLASS-sizeof.ATESTCLASS+ATESTCLASS.SomeMember] mov eax,[ebp-sizeof.ATESTCLASS+ATESTCLASS.SomeMember] ... and each will access the SomeMember member of the two different local classes and put it in eax (assuming it's a DWORD). There are more efficient ways to do this with macros, but when you compile them, this is what they come down to. Now, if you need to have a "this" pointer passed to this function (the "hidden" parameter Mr. Grysztar mentioned), typically, it would be the first parameter of the function, that is... mov eax,[ebp+8] ... and eax will have your object. Some calling standards will pass the object in a register such as ecx. Anyhow, you can then access your "this" object using the same method as ebp addressing, only with positive indexes... mov edx,[eax+ATESTCLASS.SomeMember] ... in fact, you can do this same for any instance passed as parameter, as long as your CLASS macro will allow addressing your class this way. As for the end of the procedure, you only need to top it off in the following fashion... ... mov eax,(return value) mov esp,ebp pop ebp ret (total size of parameters, in bytes) edit: corrected last comment Last edited by Big Red on 13 Jan 2006, 15:18; edited 2 times in total |
|||
13 Jan 2006, 13:51 |
|
Fungos Bauux 13 Jan 2006, 14:54
Plue, if you build a set of macros for emulating OO behavior, it can be very usefull for lots of ppl. Im new to fasm, but I can try help you to do something like this.
|
|||
13 Jan 2006, 14:54 |
|
Plue 13 Jan 2006, 15:12
Stack frame, that's what I need to make. Thank you.
|
|||
13 Jan 2006, 15:12 |
|
Big Red 13 Jan 2006, 16:03
No problem. As for... (which I forgot to answer)
Quote: Now here's the problem: How to do this? I can't simply write it like ordinary code and copy it to a newly allocated memory location as I create instances of the class since the code will still reference to the variables and procedures from where I copied it from. If you have one class with only primitives that you've already allocated space for and initialized, copying them to another class won't copy references but the values themselves, so you won't be copying pointers. If you have pointers to other objects or memory spaces, then yes, you'll have the reference problem like in any other language. And if you lose memory pointers by overriding them, then you get memory leaks, just like in C. You can probably get around the copying issue by emulating a constructor in an assembly function, which you can call anytime you need a local or global class of some sort. This way, if you have pointers to instances in your class, you'll create separate memory spaces for them, assuming it's what you need. For example, if you need to create one local instance, you could have... SomeFunction: (stack frame) ... lea edx,[ebp-sizeof.ATESTCLASS] stdcall ATESTCLASSConstructor,edx (here you would have your local class pointed to by eax, which is probably easier than using ebp) ... (here you would put whatever code for your class) mov edx,[eax+ATESTCLASS.SomeMember1] ... (here, at the end, you would call your Destructor method for your local class to ensure all your sub-objects are un-allocated) ... (stack frame) ret (...) ATESTCLASSConstructor: ; 1 parameter = memory space for instance mov eax,[esp+4] ;eax = memory space for instance mov DWORD [eax+ATESTCLASS.SomeMember1], ValueForSomeMember1 mov DWORD [eax+ATESTCLASS.SomeMember2], ValueForSomeMember2 invoke LocalAlloc,LPTR,(size of sub object) mov DWORD [eax+ATESTCLASS.SubObject1],eax sdtcall SubObject1Constructor,eax mov eax,[esp+4] ;you can return the memory space again for easier access ret 4 ... If you needed SomeFunction to return a class that will be valid after the function call, you would simply need to allocate the memory using LocalAlloc or such and use the constructor on that memory space. You might also want a second constructor if you want the constructor itself to allocate the memory. If you needed to copy values from another class, you could do so after calling the constructor, so that you can access your sub-objects and copy the values in the sub-objects instead of copying their references and sharing them between parent instances (and possibly leaking memory). Even better, you could have your constructor accept parameters to assign as initial values to your class members, and pass the class members from the other objects you're copying from to your constructor to copy. Anyhow, I'm very aware that this is very inefficient assembly coding, but if you're someone who's just looking to port over C++ code, then it's a good place to start. In fact, EVERYTHING I've written here is pretty much taken directly from disassemblies of MS Compiler-generated OOP code (which is pretty horrible, but has the basics OK). The point is... it just has to work before you can optimize it! |
|||
13 Jan 2006, 16:03 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.