# 1.5 Intro to Assembly Language, MIPS Intro

## Intro to Assembly Language, MIPS Intro

### 汇编语言

* CPU的基本工作:执行大量指令(instructions)。
* 指令是CPU可执行的基本操作。
* 不同的cpu实现不同的指令集。特定CPU实现的指令集是**指令集体系结构(Instruction Set Architecture ISA)**。
  * 例子:ARM, Intel x86, MIPS, RISC-V, IBM/Motorola PowerPC (old Mac), Intel IA64, ...

### Instruction Set Architectures 指令集架构

* 早期的趋势是向新的cpu添加越来越多的指令来做复杂的运算，
  * VAX架构有一个乘法多项式的指令!
* RISC 哲学(Cocke IBM, Patterson, Hennessy, 1980年)
  * 简化指令集计算保持指令集小而简单，使它更容易建立快速的硬件。
  * 让软件通过组合更简单的操作来完成复杂的操作。

### MIPS Architecture MIPS 架构

* MIPS&#x20;
  * 建立了第一个商用RISC架构之一的半导体公司。
  * MIPS简单、优雅。不陷入细节的纠缠。
  * MIPS广泛用于嵌入式应用，x86很少用于嵌入式，嵌入式计算机比PC多

### Assembly Variables : Registers 寄存器

* 汇编不能使用变量
  * 为什么？为了保持硬件简单
* 汇编操作数是寄存器 Assembly Operands are registers
  * 直接构建到硬件中的特殊位置的数量有限 Limited number of special locations built directly into the hardware
  * 操作只能在这些上执行! Operations can only be performed on these!
* 优点:因为寄存器直接在硬件中，所以速度非常快(比1纳秒还快)

### Number of MIPS Registers

* 缺点:由于寄存器在硬件中，所以预先确定了寄存器的数量
  * 解决方案: MIPS代码必须非常小心地 put together to efficiently use registers
* 32 registers in MIPS
  * 为什么32 ?越小越快，但太小就不好了。
* 每个MIPS寄存器都是 32 bits wide
  * Groups of 32 bits called a *word* in MIPS
  * `MIPS register = 32 bits = 1 word = 4 bytes`

### Names of MIPS Registers

* 寄存器的编号是从0到31
* 每个寄存器都可以通过编号或名称进行调用
* Number references:
  * `$0, $1, $2, … $30, $31`
* For now:
  * `$16 ~ $23 → $s0 ~ $s7`        (correspond to C variables对应C变量)
  * `$ 8 ~ $15 → $t0 ~ $t7`    (correspond to temporary variables对应临时变量)
* 通常，使用名称可以使您的代码更具可读性

### C, Java variables vs. registers

* 在C语言(以及大多数高级语言)中，变量声明并给定一个类型
* 每个变量只能表示它声明为的类型的值(不能混合和匹配int和char变量)。
* 在汇编语言中，寄存器没有类型; **操作(operation)** 决定如何处理寄存器内容

### 整数的加法和减法(Addition and Subtraction of Integers)

#### 汇编加法

Example：\
`add $s0,$s1,$s2` (in MIPS)\
Equivalent to:\
`a = b + c` (in C)\
where C variables ⇔ MIPS registers are:\
`a ⇔ $s0`\
`b ⇔ $s1`\
`c ⇔ $s2`

#### 汇编减法

Example:\
`sub $s3,$s4,$s5` (in MIPS)\
Equivalent to:\
`d = e - f` (in C)\
where C variables ⇔ MIPS registers are:\
`d ⇔ $s3`\
`e ⇔ $s4`\
`f ⇔ $s5`

#### Addition and Subtraction of Integers Example 1

How to do the following C statement?\
`a = b + c + d - e;`

Break into multiple instructions

```
add $t0,$s1,$s2 # temp = b + c
add $t0,$t0,$s3 # temp = temp + d
sub $s0,$t0,$s4 # a = temp - e
```

* 单行C可以分解成几行MIPS。
* 注意临时寄存器的使用
  * don’t want to modify the variable registers $s
  * 每行上的 # 符号之后的所有内容都会被忽略(注释)

### Immediates 即时

* Immediates 是数值常数。
* 它们经常出现在代码中，因此对它们有特殊的指令。
* Add Immediate: &#x20;

  `addi $s0,$s1,-10`     (in MIPS) &#x20;

  `f = g - 10`                 (in C) &#x20;

  where MIPS registers $s0,$s1 are associated with C variables f, g&#x20;
* 语法类似于add指令，只是最后一个参数是一个数字，而不是寄存器。\
  `add $s0,$s1,$zero` (in MIPS)\
  `f = g` (in C)

  **Overflow handling in MIPS MIPS中的溢出处理**

提示:由于计算机的精度有限，Overflow occurs when there is a “mistake” in arithmetic

* 一些语言检测溢出 (Ada)，一些不检测 (大多数C)
* MIPS的解决方案是两种算术指令 (2 kinds of arithmetic instructions: ):

  * 这些会导致检测到溢出
    * add(add)
    * add  immediate (addi)
    * subtract (sub)
    * 这些不会导致溢出检测
      * add unsigned (addu)
      * add immediate unsigned (addiu)&#x20;
      * subtract unsigned (subu)
  * 编译器选择合适的 arithmetic&#x20;
  * MIPS C compilers produce addu, addiu, subu

  **Data Transfer: Load from and Store to memory**

![img](https://github.com/chenyuxiang0425/CS-NoteBook/tree/8db905d215070b88362514c97d364c1aa08a4949/CS61C//img/dataTransfer.png)

### 内存地址以字节(Bytes)为单位

* 很多数据都小于32位，但很少有小于8位的——如果所有数据都是8位的倍数效果很好
* 8 bit 称为 a byte (1 word= 4 bytes)
* 内存地址以字节(Bytes)为单位,而不是word
* Word addresses are 4 bytes apart  字地址之间相隔4个字节
  * Word address is same as address of leftmost byte (i.e. Big-endian) Word address 与最左边 byte 的地址相同 (大端法)

    ![img](https://github.com/chenyuxiang0425/CS-NoteBook/tree/8db905d215070b88362514c97d364c1aa08a4949/CS61C//img/memoryAddressAreInBytes.png)

### Transfer from Memory to Register && Transfer from Register to Memory

```c
int A[100];
g = h + A[3];
```

Using Load Word (lw) in MIPS:

```
lw $t0, 12($s3)  # Temp reg $t0 gets A[3]
add $s1,$s2,$t0  # g = h + A[3]

# Note:
# $s3 – base register (pointer) 基本寄存器(指针)
# 12 – offset in bytes 偏移量，以字节为单位
# 偏移量必须是常数  at assembly time
```

```c
int A[100];
A[10] = h + A[3];
```

Using Store Word (sw) in MIPS:

```
lw $t0, 12($s3)  # Temp reg $t0 gets A[3]
add $t0,$s2,$t0  # Temp reg  $t0 gets h + A[3]
sw $t0,40($s3) # A[10] = h + A[3] 

# Note:
# $s3 – base register (pointer) 基本寄存器(指针)
# 12,40 – offset in bytes 偏移量，以字节为单位
# $s3+12和$s3+40必须是4的倍数,当你使用的是lw
```

## Loading and Storing bytes

* 除了 word 数据传输(lw, sw)， MIPS有 byte 数据传输:
  * load byte: lb
  * store byte: sb
  * Same format as lw, sw
  * E.g.,  `lb $s0, 3($s1)`
    * contents of memory location(内存地址的内容) with address = sum of “3” + contents of register (寄存器的内容) $s1 is copied to the low byte position of register (寄存器的低字节位置) $s0.

      ![img](https://github.com/chenyuxiang0425/CS-NoteBook/tree/8db905d215070b88362514c97d364c1aa08a4949/CS61C//img/loadingAndStoringBytes.png)

### Speed of Registers vs. Memory

Given that

* Registers: 32 words (128 Bytes)
* Memory: Billions of bytes (2 GB to 8 GB on laptop)

and the RISC principle is…

* Smaller is faster

寄存器比内存快多少?

大约快100-500倍!

* in terms of latency(延迟) of one access

### exercise

We want to translate `*x = *y +1` into MIPS (x, y pointers stored in: $s0 $s1)

A: `addi $s0,$s1,1`

B: `lw $s0,1($s1)`\
`sw $s1,0($s0)`

C: `lw $t0,0($s1)`\
`addi $t0,$t0,1`\
`sw $t0,0($s0)`

D: `sw $t0,0($s1)`\
`addi $t0,$t0, 1`\
`lw $t0,0($s0)`

E: `lw $s0,1($t0)`\
`sw $s1,0($t0)`

Answer: \[correct=c]\
We must first load the contents of y’s pointee into a temp variable \[$t0], which is 5. Then we have to store $t0 back into x’s pointee, which is 6.

### MIPS Logical Instructions

对 word 内的 bit 字段进行操作非常有用

| Logical operations | C  operators | Java operators |    MIPS instructions    |
| :----------------: | :----------: | :------------: | :---------------------: |
|   Bit-by-bit AND   |       &      |        &       |           and           |
|    Bit-by-bit OR   |      \|      |       \|       |            or           |
|   Bit-by-bit NOT   |      \~      |       \~       |           not           |
|     Shift left     |      <<      |       <<       | sll(shift left logical) |
|     Shift right    |      >>      |       >>>      |           srl           |

### Logic Shifting

* Shift Left: `sll $s1,$s2,2 #s1=s2<<2`

  * Store in $s1 the value from $s2 shifted 2 bits to the left (they fall off end), **inserting 0’s** on right; << in C.
  * Before:  &#x20;

    0000 0002hex &#x20;

    0000 0000 0000 0000 0000 0000 0000 0010two
  * After:      &#x20;

    0000 0008hex &#x20;

    0000 0000 0000 0000 0000 0000 0000 10**00**two &#x20;

    What arithmetic effect does shift left have?

  Shift Right: **srl** is opposite shift; >>

  * 向右移位运算向右移动n位(将高阶符号位插入空位)
  * For example, if register $s0 contained

    1111 1111 1111 1111 1111 1111 1110 0111two= -25ten
  * If executed sra $s0, $s0, 4, result is:

    1111 1111 1111 1111 1111 1111 1111 1110two= -2ten
  * 不幸的是，这和除以2^n是不一样的
  * Fails for odd(奇数) negative(负数) numbers
  * C的算术语义是 division 应该四舍五入到0,但现在的结果是-2

### Computer Decision Making

* MIPS: if-statement instruction is

  `beq register1,register2,L1`
* means: go to statement labeled L1 `if (value in register1) == (value in register2)`  ….otherwise, go to next statement
* beq 表示 equal 分支
* bne 表示 not equal

### Types of Branches

* branch——控制流的更改
* Conditional Branch——根据比较结果改变控制流
  * 分支如果相等(beq)
  * 分支如果不相等(bne)
* Unconditional Branch——always branch
  * jump(j)

### Example if Statement

```
f → $s0        g → $s1      h → $s2
i → $s3        j → $s4
```

```c
  if (i == j)            
    f = g + h;
```

```
bne $s3,$s4,Exit
add $s0,$s1,$s2
Exit:
```

* May need to negate branch condition

### Example if-else Statement

```c
  if (i == j)            
    f = g + h;
  else
    f =g - h
```

```
bne $s3,$s4,Else
add $s0,$s1,$s2
j Exit
Else:    sub $s0,$s1,$s2
Exit:
```

### Inequalities in MIPS

* 到目前为止，我们只测试了等式(==和!=在C语言中)。一般的程序也需要测试<和>。
* 引入MIPS不等式指令:“Set on Less Than”

  Syntax: `slt reg1,reg2,reg3`

  Meaning:

  ```c
  if (reg2 < reg3)
      reg1 = 1;
  else reg1 = 0;
  ```

  “set” means “change to 1”,\
  “reset” means “change to 0”.

### Inequalities in MIPS Cont.

我们如何使用它?手工编译:

```c
if (g < h) goto Less; #g:$s0, h:$s1
```

```
slt $t0,$s0,$s1 # $t0 = 1 if g<h
bne $t0,$zero,Less  # if $t0!=0 goto Less
```

* 寄存器 $zero 总是包含值0，因此 bne 和 beq 经常在 slt 指令之后使用它进行比较
* sltu treats registers as unsigned

### Immediates in Inequalities

slti: 一个针对常量进行 slt 的版本

```
Loop:     . . .
slti $t0,$s0,1    # $t0 = 1 if $s0<1
beq  $t0,$zero,Loop  
# goto Loop  
# if $t0==0
# (if ($s0>=1))
```

### Loops in C/Assembly

Simple loop in C;\
A\[] is an array of ints

```c
do {    g = g + A[i];
i = i + j;        
} while (i != h);
```

Use this mapping:

g, h, i, j, \&A\[0]\
$s1, $s2, $s3, $s4, $s5

```
Loop: sll  $t1,$s3,2    # $t1= 4*i        
      addu $t1,$t1,$s5  # $t1=addr A+4i   
      lw   $t1,0($t1)   # $t1=A[i]    
      add  $s1,$s1,$t1  # g=g+A[i]
      addu $s3,$s3,$s4  # i=i+j    
      bne  $s3,$s2,Loop # goto Loop if i!=h
```

answer: do ... while loop

### Conclusion:

* 32 register in MIPS
* `MIPS register = 32 bits = 1 word = 4 bytes`
* 计算机 words 和 vocabulary 分别称为指令和指令集
* 严格的格式:1 operation, 2 source operands, 1 destination
* add,sub,mul,div,and,or,sll,srl,sra
* lw,sw,lb,sb to move data to/from registers from/to memory
* beq, bne, j, slt, slti for decision/flow control
* 从 C 到 MIPS "算术表达式，数组访问，if-then-else" 的简单映射


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://chenyuxiang0425.gitbook.io/cs-notebook/cs61c/cs61c1-5.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
