I finished the TECS projects several weeks ago but still think about them on a daily basis, as they provided the foundation of my current meager understanding of hardware, software, and all the layers of abstractions involved in the interface. I don't know too much about "real world" hardware and software platforms, but I understand they operate in a similar fashion. However, the one abstraction from TECS that was the hardest for me to relate to what I understand of real computers was the VM stage. For one, in my mind the VM concept is already associated with something much more complex, i.e. running a virtual computer inside a computer (like with VMware or something). But I guess a stack-based machine abstraction is the most minimal version of that, sort of like the Jack "operating system" consisting of little more than I/O and Math libaries is a very minimal version of what I'm used to calling an operating system in the real world (Windows). Or maybe that is a different kind of VM, designed for a different purpose than the stack-based machine abstraction presented in TECS.
My main question though: in a real high level language like C, is there a VM abstraction between C code and assembly code for whatever hardware it's being compiled for? I've heard of "object code" before but I don't know very much about it.
I know with Java obviously there is the JVM, but that is more for portability than it is just for the sake of a conceptual abstraction to make coding easier (I kind of felt like the latter was the purpose of the VM in TECS... is that right?). Plus when I think of a high level language in which one writes OS's, I think of C. Based on how I've used PC's in the real world, the VM is a program which gets installed on top of an OS, versus here how we wrote an OS on top of a VM.