Bare Metal JavaScript: The JavaScript Virtual Machine

CPU Memory Management

Miško Hevery

Miško Hevery

Qwik Creator (Previously Angular)
Bare Metal JavaScript: The JavaScript Virtual Machine

Check out a free preview of the full Bare Metal JavaScript: The JavaScript Virtual Machine course

The "CPU Memory Management" Lesson is part of the full, Bare Metal JavaScript: The JavaScript Virtual Machine course featured in this preview video. Here's what you'd learn in this lesson:

Miško explores memory management and introduces the concept of a program section and a data section in CPU memory. How CPU registers are used to load, store, and manipulate data within these memory sections is also discussed in this segment.


Transcript from the "CPU Memory Management" Lesson

>> So I showed you a very simple way of adding stuff, but the ad I showed you was kind of lying because it fixed the location in memory, where we basically were adding constants, right? And that's not a real thing. So let's do a more realistic example. Okay, so a more realistic example is that we have basically a program section and a data section.

So in the program section we have our code does the stuff and in the data section we just have our data. This is where we store our local variables, your objects, etc, right? Now modern CPUs. Okay, before we actually go there, you can imagine that you can easily get yourself in trouble and have the CPU start executing data.

And then all kinds of hell will break loose. Usually the computer will crash. But if the code is malicious, maybe I can manipulate the data to look like Instructions that do stuff that the CPU isn't supposed to be doing, right. And that's basically where a lot of the exploits come in which is that you overwrite a buffer basically the software assumes that the data is receiving is this big but you send that that big.

And so, you overwrite the section over here because the receiving software is not well guarded against this. And then, this thing over here happens to be code that the program actually that's running. And by overwriting the program, all of a sudden you get to control the stuff. This is how many of the issues happen around, you send somebody JPEG and it's executable.

Well, some setting was incorrect. Things got overwritten when they weren't supposed to. The parsing program was not clean enough in terms of making sure that everything was correct. It overwrote stuff that it wasn't supposed to, and then it executed it later, and then all hell breaks loose. So modern CPUs have things like memory management, where you separate out see a memory section and say this you're allowed to execute, but you're not allowed to write into it or read on it, or the only reads that can happen is out of the program counter, no other way.

You can mark pages as data only, meaning that you're not allowed to execute any code in here. So modern CPUs have this and that helps certainly with a lot of tricks but still we see issues all the time about this. And this is why low level languages like C and C++ and an assembly are kind of dangerous because they allow you to do anything.

It's their power but also their downfall and this is why our rust is becoming popular is because rust has compiled some guarantees that the memory will not be overwritten. And because of that it's much more difficult if not I mean I guess you could say in theory impossible to get something wrong in Rust in terms of your exploits, right.

Whereas it's relatively easy in C. Again, JavaScript is also a managed language. You don't have to worry about memory. You don't have to worry about overriding things because the VM hopefully was written correctly, and won't allow you to do any of these things. So we have now a code section and a data section.

The way this would work is that we have a special register called an address register. And this register we load 13. What's 13? Well it's just a location of this if you start counting 0 1 2 3 4 5 6 7 8 this is 13. Now you can see how this is a problem like I'm supposed to remember that's 13 like that's craziness right so we'll talk about it in a second.

So that's 13 and here is next instruction. So this is a second register called AE0. Again, I'm making these things up. The actual CPU registers have different names over the years, whatever, that's not important. But fundamentally, they work the same way. And this is an offset. So in this particular case, we're saying, look, 13 is the location where the data is, and I'm interested in the 0th offset.

So 0 plus 13 is the address I'm interested in, right? And from this location, I'm gonna load the A0 plus AE0 to R0. So I'm gonna take the value 3 and move it into the R0 register, right? Now I'm gonna load a new constant into A0, which is 1.

And I'm gonna run the same exact instruction to say, now fetch the next thing, and now I'm gonna fetch 5, right? And now I can do a basic operation of addition. And now I have to do the reverse now I have to load yet another address where I want to store something and in this case I'm gonna say you can now store the R0 to the address of A0 plus AE0, right?

And now you get the output. So let's run this. So if I run this, let's see. So you can see the memory before, oops, the memory before we have here, and you can see that there's a 0 and 5 and a 0 location, and then after the code was finished running, there's an 8.

All right, and you can follow along basically what's happening in here. And so the simplest possible CPU you can imagine, basically has two general purpose registers which will just call R0 and R1 and has a special address and address extend or offset register that you can see over here.

This basically stores like your base address of something. And this store is the offset and then you can do lookups by the base plus offset. Now if you're looking at this you should be going, gee, this looks very familiar. What does it look like? Does this reminds you of array access?

Where the A0 contains the pointer to the array and AE0 contains the offset of an element in an array.
>> Yeah.
>> Right? And so, this is why when you talk about CPUs you have to kind of realize like on end of the day everything is just the array access.

So the CPU really deals with everything as array offsets. And so we can do basic operations so what I've shown you is how to load data how to kind of think about it that the CPUs have a code section and a Data section. And so let's build something more complicated.

Let's go to the next level up.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now