NOTE: this website is out of date. This is the course web site from a past quarter. If you are a current student taking the course, you should visit the current class web site instead. If the current website is not yet visible by going to cs111.stanford.edu, it may be accessible by visiting this link until the new page is mounted at this address. Please be advised that courses' policies change with each new quarter and instructor, and any information on this out-of-date page may not apply to you.
In this extra optional problem, you can implement the code for the "base and bound" design. We can't fiddle with the actual virtual memory system, so instead we've designed a simulation program that enacts how virtual memory is implemented in a simulated setting.
Specifically, we've provided a class VirtualMemory that represents a program's virtual address space, managed using the "base and bound" design. You create one by specifying how big the virtual memory space should be
// Initialize our virtual address space with 1000 bytes
VirtualMemory v_mem(1000);
VirtualMemory has base and bound instance variables to store the base and bound for the memory region:
char *base;
size_t bound;
How do we get a pointer to this fake virtual address space? You can get a pointer to the start like this:
/* Get a virtual pointer to the start of the memory space.
* A VirtualPointer can be used just like a
* regular char * pointer.
*/
VirtualPointer ptr = v_mem.get_start_ptr();
A VirtualPointer is a simulated pointer type that we've defined that hooks into VirtualMemory. We need the ability to intercept every memory access, and we can't easily do that with a real program's pointers unless we're the OS :) So instead, we defined a custom type VirtualPointer set up so that every time someone dereferences one, it will call a function translate that we will write the code for. A VirtualPointer behaves just like a regular char * pointer, though - we have implemented the functionality to allow you to dereference it (which calls translate), do pointer arithmetic with it, and print it out:
*ptr = 'h';
*(ptr + 5) = 'z';
cout << ptr + 5 << endl;
When we print it, it prints a hex number that is the offset. E.g. the above would print:
0x5
Your task is to implement the translate method within VirtualMemory; it takes in a VirtualPointer (a virtual address) and should use the base and bound to translate it to a physical address (represented as a char *) and return that. If the virtual address's offset is invalid (i.e. outside segment bounds) you should print an error message, then cause a segmentation fault like this: raise(SIGSEGV), and then return nullptr (that line will never be reached, but otherwise C++ will complain about no return value).
char *translate(const VirtualPointer& p);
Remember the steps for base and bound:
- Compare offset to the bound, error if >=
- Otherwise, add the base to virtual address offset to produce physical address
You can get the offset of a VirtualPointer by doing p.offset.
Task: implement the translate method and test it by running the provided test program, which attempts to access 3 addresses, the first two of which are valid, and the third of which is invalid and should cause a crash.
int main(int argc, char *argv[]) {
VirtualMemory v_mem(kMemorySize);
VirtualPointer ptr = v_mem.get_start_ptr();
*ptr = 'h';
cout << "Data at virtual address " << ptr << " is: " << *ptr << endl;
VirtualPointer newPtr = ptr + (kMemorySize - 1);
*newPtr = 'e';
cout << "Data at virtual address " << newPtr << " is: " << *newPtr << endl;
VirtualPointer badPtr = ptr + kMemorySize * 2;
cout << "Trying to write to virtual address " << badPtr << endl;
*badPtr = 'l';
return 0;
}
It should output the following: (the "memory violation" line is the error message printed by translate. The "Segmentation fault" line is printed automatically by the shell after this program receives a segmentation fault).
Data at virtual address 0x0 is: h
Data at virtual address 0x3e7 is: e
Trying to write to virtual address 0x7d0
memory violation - accessing invalid offset 2000
Segmentation fault
NOTE: in a real virtual memory system, only the OS can see physical addresses; a user program is only aware of virtual addresses. You might imagine that test.cc is a user program, and translate is in the OS.