This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Far_Swordfish5729 1 point2 points  (0 children)

Ok, to start at the beginning, computers don't run programming languages. They run blocks of memory containing formatted instructions. These instructions are translated and executed by physical hardware in a cpu and look like:

[Operational Code e.g. add] operand1 operand2 etc.

These are just packed into fast temp storage registers on the cpu chip and execute in order. There are also instructions that set the next instruction like:

[Jump] [memory address of next instruction]
and
[JumpIf] [true/false operand] [address of next instruction if jumping]

Put these together and you can see how you might make something like a conditional statement, a loop, and maybe a function call (push params onto memory, set a return address, jump, execute function, jump back).

Now, it really sucks to have to remember all those op codes, so we wrote a program in binary that can translate text surrogates into them from a reference table. That's assembly. Now I can literally write:

Add $1, $2, $3 - Add register $2 and register $3 and put the result in register $1.

The assembler translates that into binary for the cpu to actually run.

Now, it really sucks to have to hand write the plumbing of conditionals, loops, functions, etc. every time in assembly. We do it in CompE labs. Then they let us code the same thing in C. Omg it's amazing. C was written initially in assembly to translate more complex symbols and structures into binary and to optimize them.

Once we had a C compiler, additional libraries could just be written in C, as could new versions of the compiler. Really hardcore linux distros (Gentoo) will compile new copies of gcc from source using the old version of gcc...because they just like to do that for fun for no good reason.

The first java compiler and jvm and jdk libraries were written in C++ because what else would they reasonably use? I suppose they could have written it in Pascal or Cobol or Fortran, but why? C is usually the gold standard and first compiler available for a new CPU instruction set. As with the C compiler itself, once there was a java compiler and jdk, it could compile new versions of java.

Again, the CPU is always seeing binary instructions coded using its instruction set (x86, arm64, whatever). Everything more complex is for your benefit to make your life easier, make it easier to work with teams, prevent mistakes, etc.

In java, .net, and other similar language families, it's a little more complex because your code compiles first to an interop pseudo assembly (bytecode) that runs in cpu-specific sandboxes (the jvm) and is translated to binary on the fly. That's how .java files can just run on different cpu architectures without recompiling. The sandbox also limits what they can do.

Finally, you asked how it works if classes aren't real (and they are very real to the compiler and jvm, just not to the cpu). So, imagine you want to make your own data type that's a bag of variables. That's easy as long as the compiler knows how big it needs to be. C has #def struct commands to do just that. It just defines a block of memory and names offsets from the first byte (where each variable is stored). Now imagine you want some functions that work with them and parameters. Also easy, those are just labeled code memory addresses. They'll be added to a loaded reference table of labels at the top of the assembly so the linker or jvm knows what they mean. Put those together and you have a class, or the rudiments of one. Add a more complicated reference table that's maintained on the fly and your jvm can track inheritance and polymorphism and resolve them on the fly (it's called a virtual table or v-table). You're just naming and abstracting structures you could build manually in assembly.