Re: i cannot make kernel calls
Since I have a little background in compiler development I might add a few things here:
Pascal and BASIC are clearly not suited for OSDev'ing, they were not built for systems programming. If you really feel comfortable with them and think there's no way you'll ever be able to learn a real language like C or (better) C++ you should probably go with what you know best. Java and C# (which is 10 times better than Java) are very interesting when it comes to writing operating systems, there's an increased interest in managed code ever since JavaOS (jee, I wonder why Sun dropped that project) and Microsoft's Singularity research project.
A Pascal compiler however really is easier to write. Pascal is a LL(1) grammar while C is a LALR(1) grammar. Unfortunately all my focus was on a C++ compiler and I still curse myself for attempting that as my first compiler project. C++ is hell to parse, take it from me! Well you don't have to take it from me, there's no sane man who would disagree; they all say so
Not many C++ compilers out there anyway.
One important part of my operating system is a dynamic optimizer which works in a dynamic translation-like fashion, except that the host and target architectures are the same (well, pretty much). Application programs are usually written as a collection of loops so if the dynamic optimizer is able to interpret what's outside the loops and optimize what's inside and put that in a cache then we can care less about the overhead. (Even in normal compilation I'm sure you're aware lexing is the most expensive part.) Self-modifying code also works since the original code is never actually played around with, just the code in the cache (which is the one running). Self-modifying code does need re-optimization sometimes, of course. Besides the usual optimizations static compilers and peephole optimizers do my dynamic optimizer can also deal with problems such as languages that enforce late binding (C++/Java, anyone?). Not to mention that some programs are compiled with low optimization flags on purpose (either they take less time to compile or the developer cares about debugging).
Then there's the other thing... Take an x86 for instance. CPUID can tell us the exact model and stepping for a CPU and thus we can make model-specific optimizations based on that (and maybe even avoid bugs in CPUs that applied erratas don't fix or for CPUs that don't support microcodes altogether, such as the infamous F00F bug - of course, there are other ways around that too). Now say a CPU doesn't support SSE2 and the application is compiled to use SSE2 - hey, since we're not natively executing the code we can just take care of that problem and translate it into non-SSE2 code. That means all of a sudden you're able to run high-end applications on low-end processors (you'll just have to be patient with them). The problem gets harder when you want to detect patterns for programs that
can take advantage of SSE2 but aren't compiled to. My approach is to try to build SSA trees.
Cheers,
Bogdan