3 ms·
The thing that really got me into this subject was building my own virtual machine and then a compiler to turn a high level language into machine code. It soun
by heads 3y ago
The thing that really got me into this subject was building my own virtual machine and then a compiler to turn a high level language into machine code.
It sounds complicated but the VM, in Python, is basically:
r = {}
mem = []
boot(mem)
pc = 0
while True:
op, args = decode(mem[pc++])
if op == “+”:
d, a, b = args
r[d] = r[a] + b
elif ...:
...
The “source” which gets “compiled” can also just be Python function calls that emit op codes — no need to get bogged down with lexing and parsing!
The thing you focus on is the semantics of representing a function call (and return) in machine code and how to manage the stack. It made C make a lot more sense e.g. defining locals up front so the compiler knows how much stack space to use. I wish I could remember more — this was all from teaching A-Level Computer Science a few years ago.
- samsquire 3y agoAgreed. I find C easier to understand than the algebra of other languages such as Haskell, Ocaml, Rust because of how C statements correspond to assembly. Memory is just a big grid of numbered locations and computing is logistics between grid locations. Execution is transition between memory locations. LEAQ or "&" (C addressof) is an address calculation or LEAQ for one of those grid locations.
- IshKebab 3y ago> C statements correspond to assembly True in the 80s maybe. Not remotely true now.
- samsquire 3y agoI don't mean that there is a 1-1 constant relation between C statements and exact assembly, but if you run gcc with -S or run objdump -b binary -Matt,x86-64 -D main.bin -m i386 ; (note: this command places the assembly and C code side next to eachother, I think you have to compile with -g debug flag with gcc) You can work that the assembly implements the semantics of C's virtual machine model and it is this that I find easier to understand than some algebraic systems. I kind of think of struct->ptrarray[indx]->struct.something corresponds to the calculation of ultimately a single memory address even if there is various shift lefts or adds or ors. Java has its template interpreter which is interesting to read about and there is copy and patch JIT compilers.
- pjmlp 3y agoYou can do the same in any compiled language, including Java. Sun's Forte Pro was one of the first IDEs to have such capability for Java.
- IshKebab 3y agoSure but the relationship between assembly and source lines can be very complicated, even for trivial code: https://godbolt.org/z/hjW4T934q https://godbolt.org/z/hjW4T934q And that capability is not remotely unique to C - look at the list of languages Godbolt supports! Not all of them support linking source code to assembly but a large number do: C++, Rust, Zig, Ada, even Dart.
- IshKebab 3y agoI don't think the correspondence between C and assembly is really significantly higher than Rust, Zig or even Go.