# Numbers and Machine Code --- CS 130 // 2021-10-04 ## Administrivia - Exam 1 was returned over the weekend + [Problem 1 Visualization](https://pythontutor.com/c.html#code=void%20bar%28int%20*x,%20int%20y%29%0A%7B%0A%20%20%20%20int%20*arr%20%3D%20malloc%283%20*%20sizeof%28int%29%29%3B%0A%20%20%20%20arr%5B0%5D%20%3D%2013%3B%0A%20%20%20%20arr%5B1%5D%20%3D%2017%3B%0A%20%20%20%20arr%5B2%5D%20%3D%2019%3B%0A%20%20%20%20//%20THIS%20IS%20THE%20SPOT%0A%20%20%20%20*x%20%3D%2023%3B%0A%20%20%20%20y%20%3D%2029%3B%0A%7D%0A%0Avoid%20foo%28int%20*x,%20int%20*y%29%0A%7B%0A%20%20%20%20*x%20%3D%205%3B%0A%20%20%20%20bar%28x%2B2,%20*y%29%3B%0A%7D%0A%0Aint%20main%28%29%0A%7B%0A%20%20%20%20int%20arr%5B3%5D%20%3D%20%7B100,%20200,%20300%7D%3B%0A%20%20%20%20int%20x%20%3D%202%3B%0A%20%20%20%20foo%28arr,%20%26x%29%3B%0A%20%20%20%20printf%28%22%25d%20%25d%20%25d%20%25d%22,%20arr%5B0%5D,%20arr%5B1%5D,%20arr%5B2%5D,%20x%29%3B%0A%7D&curInstr=0&mode=display&origin=opt-frontend.js&py=c_gcc9.3.0&rawInputLstJSON=%5B%5D) - Quiz 2 on Wednesday + MIPS, numbers, and machine code # Questions ## ...about anything? # Review ## MIPS Architecture - In this course, we will be learning the MIPS instruction set - MIPS is a RISC processor with a minimalistic number of instructions - Is very similar to ARM ## MIPS Architecture - Has $2^{32}$ memory addresses, each of which contain one **byte** (8 bits) for a grand total of 4 GB - A **word** consists of 4 bytes (32 bits) - We usually refer to memory using array notation: + `Memory[0]`, `Memory[4]`, `Memory[8]`, ... ## Basic MIPS Instructions ```mips add x, y, z # x = y + z sub x, y, z # x = y z addi x, y, c # x = y + c (c is a constant) ``` ```mips lw x, s(y) # x = Memory[y + s] sw x, s(y) # Memory[y + s] = x ``` ## Fibonacci Sequence - Suppose I'd like to create an array that contains the Fibonacci sequence ```c fib[0] = 1; fib[1] = 1; fib[2] = fib[1] + fib[0]; ... ``` - Supposing that `$s0` contains the memory address for the array, write the first parts of the MIPS assembly instructions ## Fibonacci Sequence ```mips # initialize first two spots with ones, keeping t0 and t1 # as quick-access registers to the previous two values addi $t0, $zero, 1 addi $t1, $zero, 1 sw $t0, 0($s0) sw $t1, 4($s0) # compute the next spot by adding t0 and t1 and then # updating them to the new values add $t2, $t0, $t1 sw $t2, 8($s0) addi $t0, $t1, 0 addi $t1, $t2, 0 ``` # Binary Numbers ## Counting in Binary - CPUs compute in **binary** using the contrast of low/high voltages to mean 0 and 1 - So how do we encode **numbers** in binary? ---
$437_\text{ten}$
$110110101_\text{two}$
## Counting in Binary
Decimal
Binary
Hex
0
0
0
1
1
1
2
10
2
3
11
3
4
100
4
5
101
5
6
110
6
7
111
7
8
1000
8
Decimal
Binary
Hex
9
1001
9
10
1010
A
11
1011
B
12
1100
C
13
1101
D
14
1110
E
15
1111
F
16
10000
10
17
10001
11
## Practice with Binary - Convert the following number into decimal: + $1011010_\text{two}$ - Convert the following decimal number into binary: + $277_\text{ten}$ # Negative Numbers ## Negative Numbers in Binary - We usually represent negative numbers by including a "minus sign" at the beginning of a number: $-437$ - However, when representing numbers for logic circuits, we can **ONLY** use $0$s and $1$s. - So what do we do? ## Idea 1: Using a Sign Bit - We could treat the first bit of a number as the "sign" bit where $0$ means positive and $1$ means negative + $10010$ is the same as $-0010$ + $01010$ is the same as $+1010$ - Drawbacks + Multiple representations for $0$ + Addition/subtraction is not as convenient + Confusion over where the sign bit should be ## Idea 2: - **Question:** What happens when the odometer in your car reaches this state?
![Odometer 999](https://millionmilevan.com/assets/images/999_999.JPG)
## Idea 2: Wrap Around - Numbers "wrap around" from the **largest** number $999999$ to the **smallest** $000000$ - We can do the same thing in binary! + If you add one to the largest number, it "wraps around" to the smallest negative number # Two's Complement ## Two's Complement - Most computers use **two's complement** to encode signed integer values - What is it exactly? + Non-negative numbers are represented as usual
$0000$, $0011$, $0110$ + To negate a number, you do the following: 1. Flip all the bits: $0\rightarrow 1$ and $1\rightarrow 0$ 2. Add 1 to the result + $0000$, $1101$, $1010$ ## Two's Complement - Most processors are 32-bit or 64-bit, which means values sent to the processor are encoded in 32 or 64 bits, respectively - In this class, we are using the MIPS 32-bit architecture - Another way to think about two's complement is: $1000\\;1001\\;1100\\;1010\\;0110\\;0110\\;0001\\;1110$ $(x_{31}\cdot -2^{31}) + (x_{30}\cdot 2^{30}) + \cdots + (x_{1}\cdot 2^{1}) + (x_{0}\cdot 2^{0})$ ## Two's Complement Practice - Convert each of the following numbers to decimal: --- - $1111\\;1111\\;1111\\;1111\\;1111\\;1111\\;1111\\;1111$ - $1111\\;1111\\;1111\\;1111\\;1111\\;1111\\;1110\\;0101$ - $0000\\;0000\\;0000\\;0000\\;0000\\;0000\\;0000\\;0101$ # Hexadecimal ## Counting in Hex - Representing 32-bit binary numbers is cumbersome - Often we write binary in a compressed form using **hexadecimal** (or just **hex** for short) - Decimal has ten digits $\\{0,1,2,\ldots, 9\\}$ - Binary has two digits $\\{0,1\\}$ - Hex has sixteen digits $\\{0,\ldots, 9, A, B, C, D, E, F\\}$ ## Counting in Hex - Since $16 = 2^4$, it is extremely easy to represent binary numbers in hex - Each "digit" of hex corresponds to four bits ---
Binary
Hexadecimal
0000
0
0001
1
0010
2
0011
3
0100
4
0101
5
0110
6
0111
7
Binary
Hexadecimal
1000
8
1001
9
1010
A
1011
B
1100
C
1101
D
1110
E
1111
F
## Counting in Hex - Given a binary number, we can split it up into groups of four bits and convert each group to hex - $\text{0000 0010 0100 1000 0100 0000 0010 0000}_\text{two}$ - $\text{02488020}_\text{hex}$ ## Counting in Hex - Convert the following binary number into hex - $\text{1111 1010 0001 1011 0100 1110 0010 0011}_\text{two}$ - $\text{FA1B4E23}_\text{hex}$ ## Counting in Hex - Convert the following hexadecimal number into binary - $\text{00FF33AA}_\text{hex}$ - $\text{0000 0000 1111 1111 0011 0011 1010 1010}_\text{two}$ # MIPS Machine Code ## MIPS Machine Code - Each MIPS instruction is encoded in 32-bits + `add` `$t0`, `$s1`, `$s2` + 000000 10001 10010 01000 00000 100000 --- ![R-Type Instruction](/teaching/2021f/cs130/assets/images/COD/r-type-instruction.png) ## R-Type Instructions ![R-Type Instruction](/teaching/2021f/cs130/assets/images/COD/r-type-instruction.png) --- 1. `op` (6 bits): Opcode 2. `rs` (5 bits): First operand register 3. `rt` (5 bits): Second operand register 4. `rd` (5 bits): Destination register (result) 5. `shamt` (5 bits): Shift amount 6. `funct` (6 bits): Function code ## I-Type Instructions ![I-Type Instruction](/teaching/2021f/cs130/assets/images/COD/i-type-instruction.png) --- 1. `op` (6 bits): Opcode 2. `rs` (5 bits): First operand register 3. `rt` (5 bits): Second operand register 4. `data` (16 bits): Constant or address ## R-Type VS I-Type - Which type are each of the following instructions? + add + addi + sub + lw + sw ## R-Type VS I-Type - Why do we need the I-type? Why not just implement `addi`, `lw`, and `sw` using the R-type format? + Allows us to specify larger addresses and constants + $2^5 = 32$ and $2^{16} = 65536$