├── 1151 ├── LICENSE ├── cs240 │ ├── 20150106.md │ ├── 20150108.md │ ├── 20150113.md │ ├── 20150115.md │ ├── 20150120.md │ └── 20150127.md ├── cs241 │ ├── 20150106.md │ ├── 20150108.md │ ├── 20150113.md │ ├── 20150115.md │ ├── 20150120.md │ └── 20150127.md ├── cs246 │ ├── 20150106.md │ ├── 20150108.md │ ├── 20150113.md │ ├── 20150115.md │ ├── 20150127.md │ └── 20150324.md ├── cs251 │ ├── 20150106.md │ ├── 20150108.md │ ├── 20150113.md │ ├── 20150115.md │ ├── 20150120.md │ └── 20150127.md ├── readme.md └── stat231 │ ├── 20150107.md │ ├── 20150109.md │ └── 20150114.md ├── 1165 ├── README.md ├── cs349 │ ├── 1-1.md │ ├── 10-1.md │ ├── 10-2.md │ ├── 11-1.md │ ├── 11-2.md │ ├── 12-1.md │ ├── 12-2.md │ ├── 13-1.md │ ├── 5-1.md │ ├── 5-2.md │ ├── 6-1.md │ ├── 6-2.md │ ├── 7-1.md │ ├── 7-3.md │ ├── 8-1.md │ ├── 8-2.md │ ├── 9-1.md │ └── README.md └── cs350 │ ├── README.md │ └── scheduling.md ├── 1171 ├── README.md ├── cs343 │ └── lock-taxonomy.md ├── cs452 │ └── 1-4.md ├── cs454 │ └── 1-3.md └── cs456 │ ├── 1-3.md │ └── 1-5.md ├── .gitignore ├── README.md └── new /.gitignore: -------------------------------------------------------------------------------- 1 | *.cfg 2 | -------------------------------------------------------------------------------- /1151/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Elvin Yung 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /1151/cs240/20150106.md: -------------------------------------------------------------------------------- 1 | # CS 240 Enriched 2 | ## Data Structures and Data Management 3 | #### 1/6/2015 4 | Elvin Yung 5 | 6 | **Instructor:** Alex Lopez-Ortiz 7 | 8 | The objective of this course is the cover the same material as the regular sections, but with more material. This means that the pace of the course will be faster. 9 | 10 | * Tutorial: Monday 3:30 PM - 4:30 PM, MC 4064 11 | * Textbook: Robert Sedgewick, *Introduction to Algorithms in C++* 12 | 13 | ### What is computer science? 14 | You have some information. You want to 15 | * store it - use data structures. 16 | * process it - use algorithms. 17 | * trasmit it - use networking. 18 | * display it - use graphics. 19 | * secure it - use cryptography. 20 | * collect it - use sensor networks. 21 | * learn from it - use machine learning or data mining. 22 | 23 | The more data you have, the more important the information structure is. 24 | 25 | ### Course Topics 26 | * Priority queues, heaps, treaps 27 | * Sorting, selection 28 | * Binary search trees, AVL trees, B-trees, cache oblivious B-trees 29 | * Rank/select (succinct data structures), Van Emde Boas trees 30 | * Skip lists 31 | * Hashing, cuckoo hashing, bloom filters, MapReduce(/Hadoop) 32 | * Quad trees, k-d trees, range trees, R-trees 33 | * Tries 34 | * String matching, suffix trees, suffix arrays 35 | * Data compression, Huffman coding, LZW, Burrows-Wheeler, arithmetic compression, compressed sensing 36 | 37 | ### Algorithms & Data Structures 38 | * The basic **problem**: Given an input, carry out a particular computation task. 39 | * The input is known as the **problem instance**. 40 | * The output is known as the **problem solution**. 41 | * The goal is to find an efficient way to compute the solution. 42 | 43 | * An **algorithm** is a step-by-step process to compute a problem solution, given a problem instance *I*. The algorithm *solves* the problem if for every instance it finds a valid solution. 44 | * If it doesn't work all the time, it's called a **heuristic**. 45 | * A **program** is an implementation of an algorithm using a particular computer language. 46 | 47 | ### Efficiency of solution 48 | * Running time 49 | * Space usage 50 | 51 | For a given problem we have a choice of algorithms that solve the problem. The goal of algorithm design is to devise algorithms that solve a problem, and the goal of algorithm analysis is to study the efficiency of a proposed solution. Algorithm design will be covered in CS341, and we will study algorithm analysis in this course. Specifically, we will focus on algorithms that utilize storage, where the complexity comes from handling data. 52 | 53 | ### Observation 54 | There is in general an observed correlation between the size of the input and the difficulty of the problem. 55 | 56 | -------------------------------------------------------------------------------- /1151/cs240/20150108.md: -------------------------------------------------------------------------------- 1 | # CS 240 Enriched 2 | ## Data Structures and Data Management 3 | #### 1/8/2015 4 | Elvin Yung 5 | 6 | ### Timing of programs 7 | * We have a timing function `T: Input -> R+` (or `T_p`) for each program 8 | * The reason why these timing functions aren't effective is because computer hardware always improve. Therefore the timing functions are poorly defined. 9 | * Therefore we can't use "time" *per se* to time our programs, since it is not a universal measure. 10 | * So we count the number of elementary operations performed by the program. 11 | 12 | * A **RAM**, or random access machine, is a central processor with a finite set of operations on fixd width and running in at most *c* clock cycles each. 13 | * There are two main instruction sets: **CISC** (complex instruction set computing), and **RISC** (reduced instruction set computing). 14 | * there should be more things here 15 | * So the running time of some program is the count of the number of operations, including CPU instructions, and memory instructions. 16 | 17 | We can count the running time of a program with this method: 18 | 1. Write algorithms in pesudocode. 19 | 2. Count the number of primitive operations. 20 | 21 | * We can compare the running times of two different programs/algorithms by plotting the timing function in one graph. 22 | * Since the input itself isn't plottable, we substitute the input with the input size. 23 | * Since the input size might be associated with multiple inputs, we take some one metric from all the running time data associated with that one input size (e.g. worst case, average case, etc). 24 | * Essentially, at the end we have some timing function `T_A: N -> R+` for some algorithm `A`, and `T(n) = max(T_A(I) | |I| = n)`. 25 | * Then for example, for merge sort, `T(n) = n log n`. 26 | 27 | ### Order notation 28 | * Order notation is a way to compare functions. 29 | * We introduce the order notation for some function `f`: `f(x) = O(g(x))` 30 | * **Big-O:** `f(n)` is `O(g(n))` if there exists constants `c > 0` and `n_0 > 0` such that `0 <= f(n) <= cg(n)` for all `n >= n_0`. 31 | * Essentially, this means that `f(n)` is `O(g(n))` if eventually, `g(n)` is greater than `f(n)`. In other words, eventually, `f` will grow slower than `g`. 32 | * **Big Omega:** `f(n)` is `Ω(g(n))` if there exists constants `c > 0` and `n_0 > 0` such that `0 <= cg(n) <= f(n)` for all `n >= n_0`. 33 | * **Big Theta:** `f(n)` is `Ө(g(n))` if there exists constants `c_1 > 0`, `c_2 > 0` and `n_0 > 0` such that `0 <= c_1(g(n) <= f(n) <= c_2*g(n)` for all `n >= n_0`. 34 | * **Small O:** `f(n)` is `o(g(n))` if there exists constants `c > 0` and `n_0 > 0` such that `0 <= f(n) < cg(n)` for all `n >= n_0`. 35 | * **Small Omega:** `f(n)` is `w(g(n))` if there exists constants `c > 0` and `n_0 > 0` such that `0 <= cg(n) < f(n)` for all `n >= n_0`. 36 | 37 | 38 | These are all the orders: 39 | 40 | | Order | Order in R | Order in function | Meaning | 41 | |---|------------|-------------------|---------| 42 | | O | `x <= y` | `f(x) = O(g(x))` | `f(x)` eventually grows slower than, and is upper-bounded by, `g(x)`| 43 | | Ω | `x >= y` | `f(x) = Ω(g(x))` | `f(x)` eventually grows faster than, and is lower-bounded by, `g(x)`| 44 | | Ө | `x = y` | `f(x) = Ө(g(x))` | `f(x)` grows at roughly the same rate as `g(x)`| 45 | | o | `x < y` | `f(x) = o(g(x))` | `f(x)` eventually grows strictly slower than `g(x)`| 46 | | w | `x > y` | `f(x) = w(g(x))` | `f(x)` eventually grows strictly faster than `g(x)`| 47 | 48 | -------------------------------------------------------------------------------- /1151/cs240/20150113.md: -------------------------------------------------------------------------------- 1 | # CS 240 Enriched 2 | ## Data Structures and Data Management 3 | #### 1/13/2015 4 | Elvin Yung 5 | 6 | ### More on Order Notation 7 | Stuff on proofs. 8 | 9 | ### Order Classes 10 | * $\Theta(1)$ is constant time. 11 | * $\Theta(log n)$ is logarithmic time. 12 | * $\Theta(n)$ is linear time. 13 | * $\Theta(n log n)$ is pseudolinear time, which is also called sorting time. 14 | * $\Theta(n^2)$ is quadratic time. 15 | * $\Theta(n^3)$ is cubic time. 16 | * $\Theta(2^n)$ is exponential time. 17 | * $\Theta(n^k)$ is polynomial time. 18 | 19 | * Textbooks usually emphasize that polynomial time is good. In practice, cubic and quadratic are both fairly inefficient, while pseudolinear and logarithmic are usually much better. 20 | * You should always keep in mind the size of the input for the particular problem. If $f(x) \in O(g(x))$, but the intersection point is sufficiently large, it might still be better to use the solution that runs at $g(x)$ if the input size will be mostly sufficiently small. 21 | 22 | ### Limit Definition 23 | * Let $f(n) > 0, g(n) > 0$ for all $n \geq n_0$. 24 | * Suppose that $L = \lim_{n \rightarrow \infty} \frac {f(n)} {g(n)}$. 25 | * Then: 26 | * If $L=0$, $f(n) \in o(g(n))$. 27 | * If $0 < L < \infty$, $f(n) \in \Theta(g(n))$. 28 | * If $L < \infty$, $f(n) \in w(g(n))$. 29 | 30 | ### Order Laws 31 | * $f(n) = \Theta(g(n)) \Leftrightarrow g(n) = \Theta(f(n))$ 32 | * $f(n) = O(g(n)) \Leftrightarrow g(n) = \Omega(f(n))$ 33 | * $f(n) = o(g(n)) \Leftrightarrow g(n) = \omega(f(n))$ 34 | * $f(n) = \Theta(g(n)) \Leftrightarrow g(n) = \Omega(f(n)) \land f(n) = \Omega$ 35 | * $f(n) = o(g(n)) \Rightarrow g(n) = O(g(n))$ 36 | * $f(n) = o(g(n)) \Rightarrow f(n) \neq \Omega(g(n))$ 37 | * $f(n) = w(g(n)) \Rightarrow f(n) neq \Omega(g(n))$ 38 | * $f(n) = w(g(n)) \Rightarrow f(n) \neq O(g(n))$ 39 | 40 | ### Analysis of Running Time 41 | * Given an algorithm, obtain the growth order of its running time. 42 | 43 | More stuff on stuff 44 | 45 | 46 | -------------------------------------------------------------------------------- /1151/cs240/20150115.md: -------------------------------------------------------------------------------- 1 | # CS 240 Enriched 2 | ## Data Structures and Data Management 3 | #### 1/15/2015 4 | Elvin Yung 5 | 6 | ### Summation Formulae 7 | * Arithmetic sequence 8 | * Geometric sequence 9 | * Harmonic sequence 10 | 11 | ### Techniques for Algorithm Analysis 12 | * There are two general strategies: 13 | * Use theta bounds throughout the analysis and obtain a theta bound for the complexity of the algorithm. 14 | * Prove a big-O upper bound and a matching big-omega lower bound separately to get a theta bound. Sometimes this technique is easier because arguments for O-bounds might use simpler upper bounds, and/or the arguments for omega-bounds may use simpler lower bounds. 15 | 16 | AND NOW, ONTO: 17 | 18 | ## Abstract Data Types 19 | * An **abstract data type* is a collection of data and the operations defined over it. 20 | 21 | ### List 22 | * Standard linked list 23 | 24 | ### Stack 25 | * A **stack** is a set of items stacked in order of arrivals. 26 | * It implements the following interface: 27 | * `push(x)` - pushes `x` on top of the stack. 28 | * `pop()` - removes the top item from the stack. 29 | * `peek()` - returns the top item without mutating the stack. 30 | * `isEmpty()` - returns some indicator of whether the stack is empty. 31 | * `size()` - returns the size of the stack. 32 | * Stack is an example of a **LIFO** (last in, first out) data structure. 33 | 34 | ### Queue 35 | * A **queue** is an example of a **FIFO** (first in, first out) data structure. 36 | * It implements the following interface: 37 | * `front()` - returns the item at the front of the queue. 38 | * `enqueue(x)` - pushes an item to the back of the queue. 39 | * `dequeue()` - removes the item at the front of the queue. 40 | 41 | ### Dequeue 42 | * A **dequeue** (pronounced *deck*) is essentially a queue with two ends. 43 | * It has the following interface: 44 | * `front()` 45 | * `rear()` 46 | * `frontEnqueue(x)` 47 | * `rearEnqueue(x)` 48 | 49 | ### Priority Queue 50 | * In a **priority queue** (PQ) instead of ordering objects by insertion order, items are ordered by priority. 51 | * For CS240, larger priority values indicate higher priority. (In some other implementations, a priority of 1 or A indicates highest priority.) 52 | * It has the following interface: 53 | * `insert(priotiy, value)` - inserts item with priority. 54 | * `deleteMax()` - extracts the value with the highest priority. 55 | * Using a linked list to naively implement a priority queue, `insert` runs at Ө(1) and `deleteMax` linearly searches for the highest priority item and removes it, running at Ө(n). 56 | * An array implementation is to use an unsorted array. In this case, `insert` runs at Ө(1) and `deleteMax` runs at Ө(n). 57 | * Using a sorted array (by insertion), `insert` at Ө(n) and `deleteMax` runs at Ө(1). 58 | * The choice of which implementation to use is trivial if insertions are performed much more frequently than deletions (or vice versa), but if insertions and deletions are both done very frequently, we need a better implementation that is efficient for both `insert` and `deleteMax`. 59 | * Using a heap to implement a priority queue, both `insert` and `deleteMax` run at Ө(lg n). 60 | 61 | ### Heap 62 | See [2015/01/20](20150120.md). 63 | 64 | -------------------------------------------------------------------------------- /1151/cs240/20150120.md: -------------------------------------------------------------------------------- 1 | # CS 240 Enriched 2 | ## Data Structures and Data Management 3 | #### 1/20/2015 4 | Elvin Yung 5 | 6 | ### Heap 7 | * A **max-heap** is a binary tree that has the following properties: 8 | * The **heap property**: the priotiy of the parent is always higher than the priority of the child. 9 | * Structural property: It's a complete tree, with at most one node of degree one. 10 | * The leaves at most one level apart 11 | * The bottom level is filled from left to right (**left-justified**) 12 | * A min-heap is the same, but with opposite order property. 13 | * *Theorem*: The height of a heap with n nodes is Ө(log n). 14 | * *Proof*: (basic Ө proof with $1+...+2^n < n < 1+...+2^{n+1}$) 15 | * To insert a new node to a heap, we perform the *bubble-up* technique: 16 | * Insert the new node at the bottom bottom level, at the leftmost free spot. 17 | * Compare the node's value with its parent. If it is breaking heap property, switch them. 18 | * Continue until the heap property is no longer broken. 19 | * To delete the maximum value from the heap: 20 | * Remove the root. 21 | * Promote the largest of the root's two children. 22 | * Continue until done. 23 | * We can represent a heap (or any binary tree in general) with an array where the children of some node at index *i* are respectively at *2i+1* and *2i+2*. The parent of *i* must then be at `floor((i-1)/2)`. 24 | * Representing the heap with an array is an example of an *implicit* data structure. Implicit data structures are very efficient spacewise because they store very little information other than the data itself, and meaning is instead carried in the arrangement of the data. 25 | 26 | * Now we can implement a priority queue using a heap, by inserting each item as a key of variable priorities, and then using `deleteMax` to dequeue. Now both operations run at $\theta(n log n)$. 27 | 28 | #### `heapify` 29 | * `heapify` is an operation which creates a heap from some collection of data in worst case Ө(n) using a bottom-up construction method. 30 | * Essentially, starting from the smallest subtrees (at the bottom), check and swap for heap order. Do the same until root is reached. 31 | * The alternative implementation is from top-down, which is Ө(n log n) in the worst case, and Ө(n) on average case. 32 | * From the root, check and promote children, until heap property is no longer violated. 33 | 34 | #### Heap Sort 35 | * Heap sort essentially works by heapifying some collection `A`, and then running `deleteMax` until the heap is empty. 36 | * The running time of heap sort is roughly `O(n log n)`. 37 | 38 | ### Treaps 39 | * The term *treap* was coined from combining the terms *tr*ee and h*eap*. Tricky. 40 | * A treap is simultaneously a heap and a binary search tree. 41 | * Suppose we have some collection `X` in which each item has a key and a priority. 42 | * The key follows binary search property, but the priority follows the heap property. 43 | -------------------------------------------------------------------------------- /1151/cs240/20150127.md: -------------------------------------------------------------------------------- 1 | # CS 240 Enriched 2 | ## Data Structures and Data Management 3 | #### 1/27/2015 4 | Elvin Yung 5 | 6 | ### Quick Select 7 | * We previously discussed quick select, which was a method to select the *k*th item in some sorted array. 8 | * Quick select has an expected linear running time. Since the input size halves every time, the overall amount of work done for some input of size `n` is roughly `n + (n/2) + (n+4) + ... = 2n`. 9 | 10 | ### Top-k 11 | * Suppose that we have some unsorted array, and we want to return the top `k` elements. 12 | * We could heapify the array and retrieve the top `k` elements, but an even better solution is to use quick select. 13 | * This runs at roughly Ө(n + k log k). 14 | 15 | ### Quicksort Partitioning 16 | * In the in-place implementation of quicksort, keep swapping the outermost wrongly-positioned pairs around the pivot. 17 | 18 | ### Lower Bound for Sorting 19 | * Is it possible to sort in O(n)? It depends. 20 | * It depends on what you're sorting, and what you're allowed to do with the data. 21 | * For example, if you have a permutation of `1..n`, then just replace the collection with [1..n]. 22 | * In most cases, to sort at O(n) or lower, it takes some clever tricks. 23 | 24 | ### Comparison-based Sorting 25 | * **Comparison* sorting is when you attempt to sort a set of objects that are comparable to each other. 26 | * *Theorem*: Any comparison-based sort takes Ω(n log n) to sort *n* "priviate" items. 27 | * Let π be a permutation of 1..n. 28 | * sort(π) = (π^-1)(π) 29 | * In other words, sorting is the inverse of a shuffling permutation. 30 | * Then we can think of every comparison in a sorting algorithm as the process of recovering the perutation applied to the sorted input. 31 | * 32 | 33 | -------------------------------------------------------------------------------- /1151/cs241/20150106.md: -------------------------------------------------------------------------------- 1 | # CS 241 2 | ## Foundations of Sequential Programs 3 | #### 1/6/2015 4 | Elvin Yung 5 | 6 | * Instructor: Ashif Harji 7 | * ISA: Sean Harrap 8 | * Class: 10:00 AM - 11:20 AM, TTh 9 | 10 | ### What are sequential programs? 11 | * Any program that isn't concurrent or parallel is *sequential*. 12 | * This course concerns the compilation of program code, and what happens in each step. 13 | 14 | ### What happens when you compile and run a program? 15 | * Before we can answer that question, we must first ask another: *What is a compiler?* 16 | * A compiler translates code from a *source* program (usually in some sort of high level language) to an equivalent *target* program (usually in some sort of machine code). 17 | * Why do we need a compiler? 18 | * Humans write code. 19 | * Thus, we want code to be easier for people to understand. 20 | * Safety (e.g. in type) 21 | * provide abstraction 22 | * Why can't we just have the computer read the source language? 23 | * slower 24 | * relies on specific set of hardware, whereas higher language are usually machine independent. 25 | * with the computer using a lower level language, we can have multiple high level languages that all compile down to the same target. 26 | * The basic process is as follows (for a basic CS241 compiler): 27 | * Basically, the source program goes through *scanning*, or *lexical analysis*, and becomes a stream of tokens. 28 | * The tokens go through *parsing*, which generates a parse tree 29 | * The parse tree undergoes *semantic analysis*, which outputs a parse tree and a symbol table. 30 | * Then they go through *code generation*, which outputs assembly code. 31 | * The assembly code goes through the *assembler* (which is basically a simple compiler), and becomes machine code. 32 | * The assembler is a specific type of compiler that translates between assembly code and machine code. 33 | 34 | ### Bits 35 | * A *bit* is a 0 or 1, an abstraction of high/low voltages or magnets. 36 | * A *byte* is 8 bits. An example of a byte is `11001001`. There are 256 (`2^8`) possible bytes. 37 | * A *word* is a machine specific grouping of bytes, 4 or 8 bytes long (32-bit or 64-bit). In this course, we will use a 32-bit word size. 38 | * A *nibble* is 4 bits. 39 | 40 | ### Bytes 41 | * Given a byte in computer memory, what does it mean? 42 | * Without context, nothing. Everything in a computer is a stream of bits. 43 | * It could be a number. Conventionally in binary, `11001001` is 201. It is an unsigned value. 44 | * Then how are negative numbers represented? 45 | 46 | #### Sign-magnitude 47 | * Simple approach: **sign-magnitude** representation. Reserve the first bit of a byte to represent a *sign* (0 is positive, 1 is negative), and use the rest to represent the unsigned *magnitude*. 48 | * For 8 bit, we can represent numbers from -127 to 127. 49 | * Problem: there are 2 zeroes (`10000000` and `00000000`), which means you need two comparisons for null value. 50 | * Problem: adding is not symmetric. If two numbers have common sign, just add magnitude. However, if the signs are different, then use the sign of the larger magnitude and use the difference in magnitude. You need special circuits. 51 | 52 | #### two's complement 53 | To interpret an n-bit value: 54 | 1) Interpret the number as unsigned. 55 | 2) If the first bit is zero, then done. 56 | 3) Else, subtract 2^n. 57 | 58 | To get the two's complement negation of an n-bit number, subtract the number from 2^n. Alternatively, flip the bits and add one. 59 | 60 | e.g. for n=3: 61 | * `000` = 0 62 | * `001` = 1 63 | * `010` = 2 64 | * `011` = 3 65 | * `100` = -4 66 | * `101` = -3 67 | * `110` = -2 68 | * `111` = -1 69 | 70 | For 8 bits, two's complement gives us the range [-128..127], with only one zero. The arithmetic is mod 2. 71 | 72 | ### Hexadecimal notation 73 | * Base 16: 0..9, A..F (or a..f) 74 | * Each hex digit is 4 bits, so `11001001` can be represented as `C9`. 75 | * Hex numbers are usually prefixed with `0x`. In the example above, `11001001` would be `0xC9`. 76 | 77 | 78 | ### Back to bytes 79 | So given a byte, how can we tell which interpretation is correct? 80 | 81 | The answer is still no. 82 | 83 | But wait! We don't even know if it is a number. It could also be a character, which *also* depends on the encoding scheme. In this course, we will assume conventional ASCII. 84 | 85 | -------------------------------------------------------------------------------- /1151/cs241/20150108.md: -------------------------------------------------------------------------------- 1 | # CS 241 2 | ## Foundations of Sequential Programs 3 | #### 1/8/2015 4 | Elvin Yung 5 | 6 | ### Cont'd 7 | What does `11001001` represent? 8 | * Number 9 | * Character 10 | * Address 11 | * Random flags 12 | * Instructions (or in our case, a part of an instruction, since our instructions are 32-bit) 13 | 14 | We can't really know. We need to remember our intent when we stored the byte. 15 | 16 | ### Machine Language 17 | Machine Language - MIPS 18 | * What does an instruction look like? 19 | * What instrutions are there? 20 | We will use a simplified flavor of MIPS with 18 different 32-bit instruction types. 21 | 22 | In order to understand how machine langauge works, we need to understand more about the architecture of the system. You might already know that in a very high level way, the CPU communicates with the RAM with some sort of bus. 23 | 24 | ### CPU 25 | The CPU is the "brains" of the computer. These parts are inside the CPU: 26 | * The **control unit** fetches and decodes instructions, coordinates I/O, and dispatches to other parts of the computer to carry them out. 27 | * The **ALU**, or **arithmetic logic unit**, is responsible for the mathematical operations, logical operations, and comparisons. 28 | * **Registers** are a small amount of memory inside the CPU. We have 32 general purpose registers (of 5 bits each). 29 | 30 | ### Memory 31 | In descending order of speed: 32 | * Registers 33 | * Cache - A part of main memory that's stored closer to the CPU that stores previously accessed data for faster reaccess time. 34 | * Main memory (RAM) 35 | * Secondary storage (Tape, HDD, network, etc.) 36 | 37 | In this course, we will mostly be concerned with registers and main memory. 38 | 39 | ### MIPS 40 | MIPS has access to 32 general purpose registers, as well as special registers such as `HI`, `LO`, `PC`, `IR`, `MAR`, and `MDR`. 41 | * `$0` always stores 0. 42 | * `$30` and `$31` are special by convention (i.e. not by hardware). 43 | 44 | An example register operation is "add the contents of the registers `s` and `t`, and store the result in `d`." (`add d,s,t`) We denote this as `$d <- $s + $t`. Since we have 5 bits per register, and 3 registers are used in this example, 15 bits need to be set aside for the registers. Since a word is 32 bits long, we have 17 bits left for the instruction. 45 | 46 | * There are two types of instructions, register and immediate. 47 | * Register instructions work entirely with registers. 48 | * Immediate instructions work with some combination of registers and immediate values, that is, literals. Immediate values are interpreted as two's complement. 49 | 50 | * Multiplication (`mult`/`multu`) gives you a 64 bit result in the reserved `HI` and `LO` registers, since multiplying 2 32-bit numbers can give you 64-bit numbers. 51 | * Division (`div`/`divu`) gives you some quotient stored in the `HI` and `LO` registers. 52 | * The `HI` and `LO` registers can be read (moved to a general purpose register) with the `mfhi` and `mflo` instructions. 53 | 54 | ### Main Memory 55 | * **RAM** stands for random access memory. This is the main memory of the computer. 56 | * This is a large amount of memory that is stored away from the CPU. For our purposes, the RAM is just a big array `n` bytes, where `n ~= 10^9` (a gigabyte). 57 | * Each byte has an address, running from 0 to `n-1`, but we group everything on words, so we will use addresses divisible by 4 (`0x0`, `0x4`, etc.), and each 4-byte block is a word. 58 | * The data travels between the CPU and the RAM on a bus, which we can think of as 64 wires connecting the two components. Accessing RAM is much slower than accessing registers. 59 | * The CPU interacts with the bus using the `MAR` (memory address register) and `MDR` (memory data register) registers. 60 | 61 | To move data between the RAM and CPU: 62 | * Load: transfer a word from a specified address to a specified register. The desired address goes into the `MAR` register, and the and then goes out onto the bus. When it arrives at the RAM, the associated data is sent back from the bus onto the `MDR` register, and then moved onto the destination register. 63 | * Store: Exactly like load, but in reverse. 64 | 65 | ### Programs 66 | * How does the computer know which words contain instructions and which contain data? 67 | * Surprise! It doesn't. There is a special `PC` (program counter) register, which holds the address of the next instruction to run. 68 | * The `IR` register stores the current instruction. 69 | * By convention, we guarantee that some fixed address contains code, and then initialize PC to whatever the fixed address is. 70 | * Then, the control unit runs the fetch-execute cycle. In pseudocode, this is the fetch-execute cycle: 71 | 72 | ``` 73 | PC <- 0 74 | loop 75 | IR <- MEM[PC] 76 | PC <- PC + 4 77 | decode and execute instruction at IR 78 | end loop 79 | ``` 80 | 81 | TODO: reword this 82 | * How does a program get executed? 83 | * There is a program called the loader, which puts the program in memory, and sets `PC` to the address of the first instruction in the program. 84 | * What happens when the program ends? 85 | * We need to return control to the loader. `PC` is set to the address of the next instruction in the loader. 86 | * Which instruction is that? 87 | * `$31` will by convention store the correct address to retunr to, so we just need to set PC to `$31`. 88 | * We will use the jump register command (`jr`) to update the value of `PC`. 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /1151/cs241/20150113.md: -------------------------------------------------------------------------------- 1 | # CS 241 2 | ## Foundations of Sequential Programs 3 | #### 1/13/2015 4 | Elvin Yung 5 | 6 | ### Examples 7 | * Example: Add 2 values in registers 5 and 7, storing the result in register 3, then return 8 | 9 | | Assembly | Location | Binary | Hex | 10 | |------|--------|--------|----------| 11 | | `add $3, $5, $7` | `0x0000` | `0000 0000 1010 0111 0001 1000 0010 0000` | `0x00a71820` | 12 | | `jr $31` | `0x0004` | `0000 0011 1110 0000 0000 0000 0000 1000` | `0x03e00008` | 13 | 14 | * Example: Add 42 and 52, store sum in $3, and then return 15 | 16 | | Assembly | Location | Binary | Hex | 17 | |------|--------|--------|----------| 18 | |`lis $5` | `0x0000` | `0000 0000 0000 0000 0010 1000 0001 0100` | `0x00002814` | 19 | |`.word 42` | `0x0004` | `0000 0000 0000 0000 0000 0000 0010 1010` | `0x0000002a` | 20 | |`lis $7` | `0x0008` | `0000 0000 0000 0000 0011 1000 0001 0100` | `0x00003814` | 21 | |`.word 52` | `0x000c` | `0000 0000 0000 0000 0000 0000 0011 0100` | `0x00000034` | 22 | |`add $3, $5, $7` | `0x0010` | stuff | more stuff | 23 | |`jr $31` | `0x0014` | stuff | more stuff | 24 | 25 | * You can use the command `xxd` to get a hex dump of your mips file thing, to verify that you converted stuff from hex correctly. 26 | 27 | ### Assembly Language 28 | * We will begin writing our programs not in binary or hex, but with simple mnemonics. 29 | * There is a direct translation back to te required binary (assembler). 30 | * Each assembly instruction corresponds to one machine instruction (almost -- `.word` isn't a thing because it's just a word). 31 | * We will revisit the previous example: 32 | 33 | ```nasm 34 | lis $5 ; $5 <- 42 35 | .word 42 36 | lis $7 ; $7 <- 52 37 | .word 52 ; $3 <- $5 + $7 38 | add $3, $5, $7 ;pc <- $31 39 | jr $31 40 | ``` 41 | 42 | ### Jumping 43 | * `beq`: go somewhere else if two registers are equal 44 | * `bne`: go somewhere else if two registers are not equal 45 | * Both instructions increment the PC by a given number of words (forward or backward). 46 | * Based on the fetch-execute cycle, PC has already been incremented to point at the next instruction, before the instruction has been decoded and executed. Hence, offset is relative to the next instruction. 47 | 48 | ### More examples 49 | #### Absolute value `$1` 50 | ```nasm 51 | slt $2, $1, $0 ; compare $1 < 0 52 | beq $2, $0, 1 ; if false, skip over 53 | sub $1, $0, $1 ; negate $1 54 | jr $31 55 | ``` 56 | 57 | #### Sum the integers `1..13`, store in `$3`, then return 58 | ```nasm 59 | add $3, $0, $0 ; $3 <- 0 60 | lis $2 ; $2 <- 13 61 | .word 13 62 | add $3, $3, $2 ; $3 += $2 63 | lis $1 ; $1 <- 1 64 | .word 1 65 | sub $2, $2, $1 ; $2 -= 1 66 | bne $2, $0, -5 ; jump 5 things back 67 | jr $31 68 | ``` 69 | 70 | -------------------------------------------------------------------------------- /1151/cs241/20150115.md: -------------------------------------------------------------------------------- 1 | # CS 241 2 | ## Foundations of Sequential Programs 3 | #### 1/15/2015 4 | Elvin Yung 5 | 6 | ### Programs with RAM 7 | * `lw` is the *load word* instruction. It loads a word from RAM into a register. 8 | * syntax: `lw $a, c($b)`, loads the word at `MEM[c+$b]` into `$a`. 9 | * `sw` is the *store word* instruction. It stores a word from register into RAM. 10 | * syntax: `sw $a, c($b)`, stores the word at `$a` into the memory location `MEM[c+$b]`. 11 | 12 | #### Example: Array indexing 13 | * The register `$1` holds the address of an array, and `$2` holds the length of the array. Retrieve the element with index 5, and store it in register `$3`. 14 | 15 | ```nasm 16 | lw $3, 20($1) ; 5*4 = 20 17 | jr $31 18 | ``` 19 | 20 | * Suppose we want to work with arbitrary indices. We introduce the following instructions: 21 | * `mult` is the *multiply* instruction. Since multiplying two 32-bit numbers might result in a 64-bit number, the results are stored in two special registers `hi` and `lo`. 22 | * syntax: `mult $a, $b` 23 | * `div` is the *divide* instruction. The quotient is stroed in `lo`, and the remainder is stored in `hi`. 24 | * syntax: `div $a, $b` 25 | * `mfhi` and `mflo` are the *move from HI* and *move from LO* instructions. They move the values from `hi` or `lo` respectively into a given register. 26 | * syntax: `mfhi $d`, `mflo $d` 27 | 28 | ```nasm 29 | lis $5 ; load the arbitrary index into $5 30 | .word SOME_INDEX 31 | lis $4 ; load the value 4, the size of a word, into $4 32 | .word 4 33 | mult $5, $4 ; obtain the offset we need by multiplying the index and the size of a word 34 | mflo $5 ; move the offset we need into $5 35 | add $5, $1, $5 ; offset $5 by $1, which stores the address of the array 36 | lw $3, 0($5) ; load the address we need from memory into $3 37 | jr $31 38 | ``` 39 | 40 | ### Labels 41 | * Recall, in the previous loop example (cf. [notes from 01/13](20150113.md), *Sum the integers `1..13`, store in `$3`, then return*) that the `lis` command was inside the loop, which could be moved outside. 42 | * That is fine, but the `bne` at the end now has an improper immediate/offset (should be -3 instead of -5). 43 | * In nested loops/branches, this is bad. Since we hardcoded branch offsets, we need to change them every time we add or remove instructions inside a loop. 44 | * Instead, the assembler allows for *labelled* instructions: `