### Operating Systems

*Elements of Computing Systems, Nisan & Schocken, MIT Press www.idc.ac.il/tecs*

### www.nand2tetris.org

*Building a Modern Computer From First Principles*

### Where we are at:

Assembler Chapter 6

**H.L. Language**

**&**

**Operating Sys.**

abstract interface

**Compiler**

Chapters 10 - 11

**VM Translator**

Chapters 7 - 8

**Computer** **Architecture**

Chapters 4 - 5

**Gate Logic**

Chapters 1 - 3

**Electrical**

**Engineering**

**Physics** **Virtual**

**Machine**

abstract interface

**Software** **hierarchy**

**Assembly** **Language**

abstract interface

**Hardware** **hierarchy**

**Machine** **Language**

abstract interface

**Hardware** **Platform**

abstract interface

**Chips &**

**Logic Gates**

abstract interface

**Human** **Thought**

**Abstract design**

Chapters 9, 12

### Jack revisited

**/** Computes the average of a sequence of integers. */**

**class Main {**

**function void main() {** **var Array a;**

**var int length;**

**var int i, sum;**

**let length = Keyboard.readInt(”How many numbers? ”);**

**let a = Array.new(length); // Constructs the array** **let i = 0;**

**while (i < length) {**

**let a[i] = Keyboard.readInt(”Enter the next number: ”);**

**let sum = sum + a[i];**

**let i = i + 1;**

**}**

**do Output.printString(”The average is: ”);**

**do Output.printInt(sum / length);**

**do Output.println();**

**return;**

**}**

**}**

**/** Computes the average of a sequence of integers. */**

**class Main {**

**function void main() {** **var** **Array** **a;**

**var int length;**

**var int i, sum;**

**let length =** **Keyboard.readInt(”How many numbers? ”);**

**let a =** **Array.new(length); // Constructs the array** **let i = 0;**

**while (i < length) {**

**let a[i] =** **Keyboard.readInt(”Enter the next number: ”);**

**let sum = sum + a[i];**

**let i = i + 1;**

**}**

**do** **Output.printString(”The average is: ”);**

**do** **Output.printInt(sum** **/** **length);**

**do** **Output.println();**

**return;**

**}**

### Jack revisited

### Typical OS functions

### Language extensions / standard library

### Mathematical operations **(abs, sqrt, ...)**

### Abstract data types **(String, Date, ...)**

### Output functions

**(printChar, printString ...)**

### Input functions

**(readChar, readLine ...)**

### Graphics functions

**(drawPixel, drawCircle, ...)**

### And more ...

### System-oriented services

### Memory management (objects, arrays, ...)

### I/O device drivers

### Mass storage

### File system

### Multi-tasking

### UI management (shell / windows)

### Security

### Communications

### And more ...

### The Jack OS

### **Math** **:** Provides basic mathematical operations;

### **String** **:** **Implements the String type and string-related operations;**

### **Array** **:** **Implements the Array type and array-related operations;**

### **Output** **:** Handles text output to the screen;

### **Screen** **:** Handles graphic output to the screen;

### **Keyboard** **: Handles user input from the keyboard;**

### **Memory** **:** Handles memory operations;

### **Sys** **:** Provides some execution-related services.

### Jack OS API

**class Math** **{**

**function void init()** **function int abs(int x)**

**function int multiply(int x, int y)** **function int divide(int x, int y)** **function int min(int x, int y)** **function int max(int x, int y)** **function int sqrt(int x)**

**}**

**Class String** **{**

**constructor String new(int maxLength)** **method void dispose()**

**method int length()**

**method char charAt(int j)**

**method void setCharAt(int j, char c)** **method String appendChar(char c)**

**method void eraseLastChar()** **method int intValue()**

**method void setInt(int j)** **function char backSpace()** **function char doubleQuote()** **function char newLine()** **}**

**Class Array** **{**

**function Array new(int size) ** **method void dispose()**

**}**

**class Output** **{**

**function void moveCursor(int i, int j)** **function void printChar(char c)**

**function void printString(String s) ** **function void printInt(int i)**

**function void println()** **function void backSpace()** **}**

**Class Screen** **{**

**function void clearScreen()**

**function void setColor(boolean b)**

**function void drawPixel(int x, int y)** **function void drawLine(int x1, int y1,**

**int x2, int y2)**

**function void drawRectangle(int x1, int y1,** **int x2, int y2)** **function void drawCircle(int x, int y, int r)** **}**

**class Memory** **{**

**function int peek(int address)**

**function void poke(int address, int value)** **function Array alloc(int size)**

**function void deAlloc(Array o)** **}**

**Class Keyboard** **{**

**function char keyPressed()** **function char readChar()**

**function String readLine(String message) ** **function int readInt(String message) ** **}**

**Class Sys** **{**

**function void halt():**

**function void error(int errorCode)**

**function void wait(int duration)**

**}**

### A typical OS:

### Is modular and scalable

### Empowers programmers (language extensions)

### Empowers users (file system, GUI, ...)

### Closes gaps between software and hardware

### Runs in “protected mode”

### Typically written in some high level language

### Typically grows gradually, assuming more and more functions

### Must be efficient.

### Efficiency

### We have to implement various operations on n -bit binary numbers ( n = 16, 32, 64, ...).

### For example, consider multiplication

### Naïve algorithm: to multiply x*y: { for i = 1 ... y do sum = sum + x } Run-time is proportional to y

### In a 64-bit system, y can be as large as 2 ^{64.}

### Multiplications can take years to complete

### Algorithms that operate on n -bit inputs can be either:

### Naïve: run-time is proportional to the value of the n -bit inputs

### Good: run-time is proportional to n, the input’s size.

### Run-time: proportional to n

### Can be implemented in SW or HW

### Division: similar idea.

### Example I: multiplication

### Example II: square root

### The square root function has two convenient properties:

### It’s inverse function is computed easily

### Monotonically increasing

### Functions that have these two properties can be computed by binary search:

### Number of loop iterations is bounded by n/2, thus the run-time is O(n).

### Math operations (in the Jack OS)

**class Math** **{**

**function void init()** **function int abs(int x)**

**function int multiply(int x, int y)** **function int divide(int x, int y)** **function int min(int x, int y)** **function int max(int x, int y)** **function int sqrt(int x)**

**}**

##

##

##

**class Math {**
**class String {**

**class Array {**
**class Output {**

**class Screen {**
**class Memory {**

**class Keyboard {**
**class Sys {**

**function (…)**

**… **
**}**

### The remaining functions are simple to implement.

### String processing ^{(} in the Jack OS)

**Class String** **{**

**constructor String new(int maxLength)** **method void dispose()**

**method int length()**

**method char charAt(int j)**

**method void setCharAt(int j, char c)** **method String appendChar(char c)**

**method void eraseLastChar()** **method int intValue()**

**method void setInt(int j)** **function char backSpace()** **function char doubleQuote()** **function char newLine()**

**class Math {**
**class String {**

**class Array {**
**class Output {**

**class Screen {**
**class Memory {**

**class Keyboard {**
**class Sys {**

**function (…)**

**… **
**}**

### Single digit ASCII conversions

### asciiCode(digit) == digit + 48

### digit(asciiCode) == asciiCode - 48

### SingleDigit–to-character conversions: done

### Number–to-string conversions:

### Converting a number to a string

### Memory management ^{(} in the Jack OS )

**class Memory** **{**

**function int peek(int address)**

**function void poke(int address, int value)** **function Array alloc(int size)**

**function void deAlloc(Array o)** **}**

**class Math {**
**class String {**

**class Array {**
**class Output {**

**class Screen {**
**class Memory {**

**class Keyboard {**
**class Sys {**

**function (…)**

**… **
**}**

### The data structure that this algorithm manages is a single pointer: free.

### Memory management (naive)

### When a program constructs (destructs) an object, the OS has to allocate (de-allocate) a RAM block on the heap:

### **alloc(size):** returns a reference to a free RAM block of size **size**

### **deAlloc(object):** recycles the RAM block that **object** refers to

### Memory management (improved)

### Peek and poke

**class Memory** **{**

**function int peek(int address)**

**function void poke(int address, int value)** **function Array alloc(int size)**

**function void deAlloc(Array o)** **}**

### Implementation: based on our ability to exploit exotic casting in Jack:

### Graphics primitives ^{(} in the Jack OS )

**Class Screen** **{**

**function void clearScreen()**

**function void setColor(boolean b)**

**function void drawPixel(int x, int y)**

**function void drawLine(int x1, int y1, int x2, int y2)** **function void drawRectangle(int x1, int y1,int x2, int y2)** **function void drawCircle(int x, int y, int r)**

**}**

**class Math {**
**class String {**

**class Array {**
**class Output {**

**class Screen {**
**class Memory {**

**class Keyboard {**
**class Sys {**

**function (…)**

**… **
**}**

### Memory-mapped screen

### Pixel drawing

### Implementation: using poke(address,value)

### screen program

### application physical

### refresh mechanism screen

### driver

### part of the part of the

### Image representation: bitmap versus vector graphics

### Bitmap file: 00100, 01010,01010,10001,11111,10001,00000, . . .

### Vector graphics file: drawLine(2,0,0,5), drawLine(2,0,4,5), drawLine(1,4,3,4)

### Pros and cons of each method.

(0,0)

### vector bitmap

### pixel

### Vector graphics: basic operations

### drawPixel(x,y)

### drawCircle(x,y,r)

### drawLine(x1,y1,x2,y2)

### drawRectangle(x1,y1,x2,y2)

**1** **2** **3** **4** **5** **6** **7** **8**

**0 1 2 3 4 5 6 7 8 9 10 11 12 13** **0**

### drawLine(0,3,0,11)

### drawRectangle(1,3,5,9) drawLine(1,12,2,12) drawLine(3,10,3,11) drawLine(6,4,6,9) drawLine(7,0,7,12) drawLine(8,1,8,12)

### (Primitive operation)

### drawTriangle(x1,y1,x2,y2,x3,y3) etc. (a few more similar operations) **1**

**2** **3** **.** **.** **.**

**0 1 2 3** **.** **.** **.** **0**

**Screen = **

**grid of pixels**

### How to draw a line?

### drawLine(x1,y1,x2,y2)

### Basic idea: drawLine is implemented through a sequence of ^{drawPixel} operations

### Challenge 1: which pixels should be drawn ?

### Challenge 2: how to draw the line fast ?

### Simplifying assumption: the line that we are asked to draw goes north-east.

### Line Drawing

### Given: drawLine(x1,y1,x2,y2)

### Notation: x=x1, y=y1, dx=x2-x1, dy=y2-y1

### Using the new notation:

### We are asked to draw a line between ^{(x,y)} and (x+dx,y+dy)

### set (a,b) = (0,0)

### while there is more work to do drawPixel(x+a,y+b)

### decide if you want to go right, or up if you decide to go right, set a=a+1;

### if you decide to go up, set b=b+1

### set (a,b) = (0,0)

### while (a ≤ dx) and (b ≤ dy) drawPixel(x+a,y+b)

### decide if you want to go right, or up if you decide to go right, set a=a+1;

### if you decide to go up, set b=b+1 *dx*

*dy*

### Line Drawing algorithm

### drawLine(x,y,x+dx,y+dy) set (a,b) = (0,0)

### while (a ≤ dx) and (b ≤ dy) drawPixel(x+a,y+b)

### decide if you want to go right, or up if you decide to go right, set a=a+1;

### if you decide to go up, set b=b+1

### drawLine(x,y,x+dx,y+dy) set (a,b) = (0,0)

### while (a ≤ dx) and (b ≤ dy) drawPixel(x+a,y+b) if b/a > dy/dx set a=a+1

### else set b=b+1

**costy**

### Line Drawing algorithm, optimized

### b/a > dy/dx is the same as a*dy < b*dx Define diff = a*dy – b*dx

### Let’s take a close look at this diff:

1.

### b/a > dy/dx is the same as diff < 0

2.

### When we set (a,b)=(0,0), diff = 0

3.

### When we set a=a+1, diff goes up by dy When we set b=b+1, diff goes down by dx drawLine(x,y,x+dx,y+dy)

### set (a,b) = (0,0)

### while (a ≤ dx) and (b ≤ dy) drawPixel(x+a,y+b) if b/a > dy/dx set a=a+1

### else set b=b+1

### drawLine(x,y,x+dx,y+dy) set (a,b) = (0,0), diff = 0 while (a ≤ dx) and (b ≤ dy)

### drawPixel(x+a,y+b)

### if diff < 0 set a=a+1, diff = diff + dx else set b=b+1, diff = diff - dy

### Motivation

### When you draw polygons, e.g. in animation or video, you need to draw millions of lines

### Therefore, drawLine must be ultra fast

### Division is a very slow operation

### Addition is ultra fast (hardware based)

### Circle drawing

### The screen

### origin (0,0)

### is at the top

### left.

### An anecdote about efficiency and design

### … Jobs obsessed about the look of what would appear on the screen. One day Bill Atkinson burst into his office all excited. He had just come up with a brilliant algorithm that could draw circles onscreen quickly. The math for making circles usually required calculating square roots, which the Motorola 68000 microprocessor didn’t support.

### But Atkinson did a workaround based on the fact that the sum of a sequence of odd numbers produces a sequence of perfect squares (e.g. 1 + 3 = 4, 1 + 3 + 5 = 9, etc.)

### When Atkinson fired up his demo, everyone was

### impressed except Jobs. “Well, circles are nice,” he said,

### “but how about drawing rectangles with rounded

### corners?”

### To do vector graphics (e.g. display a PPT file), you have to draw polygons

### To draw polygons, you need to draw lines

### To draw lines, you need to divide

### Division can be

### re-expressed as multiplication

### Multiplication can be reduced to addition

### Addition is easy.

### To sum up (vector graphics)…

### Character output primitives ^{(} in the Jack OS )

**class Output** **{**

**function void moveCursor(int i, int j)** **function void printChar(char c)**

**function void printString(String s) ** **function void printInt(int i)**

**function void println()** **function void backSpace()** **}**

**class Math {**
**class String {**

**class Array {**
**class Output {**

**class Screen {**
**class Memory {**

**class Keyboard {**
**class Sys {**

**function (…)**

**… **
**}**

### Character output

### Given display: a physical screen, say 256 rows by 512 columns

### We can allocate an 11 by 8 grid for each character

### Hence, our output package should manage a 23 lines by 64 characters screen

### Font: each displayable character must have an agreed-upon bitmap

### In addition, we have to manage a “cursor”.

**class Output {**

**static Array charMaps;**

**function void initMap() {**

**let charMaps = Array.new(127);**

**// Assign a bitmap for each character**

**do Output.create(32,0,0,0,0,0,0,0,0,0,0,0); // space**
**do Output.create(33,12,30,30,30,12,12,0,12,12,0,0); // !**
**do Output.create(34,54,54,20,0,0,0,0,0,0,0,0); // “**
**do Output.create(35,0,18,18,63,18,18,63,18,18,0,0); // #**
**...**

**do Output.create(48,12,30,51,51,51,51,51,30,12,0,0); // 0**
**do Output.create(49,12,14,15,12,12,12,12,12,63,0,0); // 1**
**do Output.create(50,30,51,48,24,12,6,3,51,63,0,0); // 2**
**. . .**

**do Output.create(65,0,0,0,0,0,0,0,0,0,0,0); // A ** TO BE FILLED ****

**do Output.create(66,31,51,51,51,31,51,51,51,31,0,0); // B**
**do Output.create(67,28,54,35,3,3,3,35,54,28,0,0); // C**
**. . .**

**return;**

**} **

### Font implementation ^{(} in the Jack OS )

**// Creates a character map array**

**function void create(int index, int a, int b, int c, int d, int e,**
**int f, int g, int h, int i, int j, int k) {**
**var Array map;**

**let map = Array.new(11);**

**let charMaps[index] = map;**

**let map[0] = a;**

**let map[1] = b;**

**let map[2] = c;**

**...**

**let map[10] = k;**

### Keyboard primitives ^{(} in the Jack OS )

**Class Keyboard** **{**

**function char keyPressed()** **function char readChar()**

**function String readLine(String message)** **function int readInt(String message) ** **}**

**class Math {**
**class String {**

**class Array {**
**class Output {**

**class Screen {**
**class Memory {**

**class Keyboard {**
**class Sys {**

**function (…)**

**… **
**}**