OK a brief explanation of what happens when you call a C function vs. a C++ object method (to my knowledge, anyway - some inaccuracies may be present!)
Say you have a "memset" function (as you do
) - in C, you'd have something like this:
Code:
void* memset(void* dest, char value, unsigned int count);
Which, if I'm not mistaken, typically becomes:
Code:
push count
push value
push dest
call memset
; your memset code here... at the end of memset "ret" is called
mov result, eax
Now, if you want to do this the way you're doing it, you'd first need to create an instance of the System class. The class acts like structural DNA - it describes an object, and you can quite happily create instance after instance of it.
In this case, you'd probably only have one single System, right? I'll pick back up on this in a moment...
When you call the memset within a class, you'd be calling it like this I guess:
Code:
System the_computer;
the_computer.memset(&foo, 0, 1234);
Consider if you had more than one System instance - there needs to be a way to work with each one individually. To save space in memory, your class's methods will usually be shared among instances, and to differentiate between each instance, a "this" pointer is passed to the methods.
So your "memset" effectively has an additional parameter, which would get pushed on the stack prior to the function call taking place. If you were doing this in C, it'd probably look like:
Code:
void* memset(System* this, void* dest, char value, unsigned int count);
This may seem redundant in this example - and it is. If you had more than one System object, however, you'd be able to tell which one the method was called on.
So IMO it's not really worth creating an object for something you're only going to have a single instance of and be using frequently.
My own approach has been to use namespaces, which basically lets you divide up functions into named groups, which seems more appropriate. So you could have
System::memset and
System::outportb. The beauty of this is that it allows you to have something that *looks* object-oriented, without any of the overhead associated with classes/objects.
Not saying that classes/objects are evil, of course - my own implementation has a few things like a Port class which is declared as inline and implemented in a header file.
Works like this:
Code:
Port master_pic_command(0x20);
Port master_pic_data(0x21);
master_pic_data.writeByte(0xff);
(note: the above port I/O with regard to the PIC may be incorrect as it's just a random example!)
In this case, I have some information associated with the object (a port number) which I'd have to push on the stack for the function call anyway otherwise
This is by no means the most optimal way to do it (most optimal way is probably not to use objects again, but since there may be multiple Ports this seemed sensible).
Sorry for rambling there...
And I just realised that you're using the System class to represent the kernel (startup/shutdown) - that'd work, but again I
personally don't see the advantage.
When the kernel runs, it'll just ultimately loop repeatedly. Something else is likely to take care of shutdown/restarts. So as far as my own kernel main() goes, I just set the environment up by using the objects and namespaces I've created.
Effectively it's that tutorial but with some fluff added to it
Another thing to beware of - name mangling. Make sure whatever code gets called from external asm (including startup code) is marked
extern "C" otherwise the linker will probably complain.
Hope this helps?