-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1c0c0d5
commit a33bbda
Showing
5 changed files
with
208 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Tmux Cheatsheet | ||
|
||
!!! info "What is tmux?" | ||
tmux’s authors describe it as a terminal multiplexer. Behind this fancy term hides a simple concept: Within one terminal window you can open multiple windows and split-views (called "panes" in tmux lingo). Each pane will contain its own, independently running shell instance (bash, zsh, whatever you're using). This allows you to have multiple terminal commands and applications running side by side without the need to open multiple terminal emulator windows. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,75 @@ | ||
# Chapter 3 Machine-Level Representation of Programs | ||
# Chapter 3 Machine-Level Representation of Programs | ||
|
||
!!! info "CMU 15-213" | ||
这里使用的 x86-64 汇编的形式是 AT&T 语法,而不是 Intel 语法。AT&T 语法与 Intel 语法的区别在于操作数的顺序,AT&T 语法是 `source, destination`,而 Intel 语法是 `destination, source`。这种描述的语法会用在 Linux 系统之中,但是当我们阅读 Intel 和 Microsoft 的代码与文档的时候,就要换换脑筋了。 | ||
|
||
|
||
??? info "Tools: Disassembler" | ||
|
||
|
||
|
||
??? info "Tools: GNU Debugger/GDB" | ||
|
||
## 3.5 Arithmetic and Logical Operations | ||
|
||
## 3.6 Control | ||
|
||
### 3.6.1 Conditional Codes | ||
|
||
除了整数寄存器,CPU 还维护着一组**单个位**的**条件码/Conditional Code** 寄存器,他们描述了最近一次算术或者逻辑操作的结果。这些条件码寄存器包括: | ||
|
||
- **CF/Carry Flag**:进位标志。如果最近一次的操作导致了一个无符号数的溢出,这也就是进位,那么 CF 就会被设置为 1。 | ||
- **ZF/Zero Flag**:零标志。如果最近一次的操作的结果为 0,那么 ZF 就会被设置为 1。 | ||
- **SF/Sign Flag**:符号标志。如果最近一次的操作的结果为负数,那么 SF 就会被设置为 1。 | ||
- **OF/Overflow Flag**:溢出标志。如果最近一次的操作导致了一个有符号数/补码的溢出,那么 OF 就会被设置为 1。 | ||
|
||
以算数操作 `t = a + b` 举例,设置条件码的操作与逻辑类似于下面的 C 代码: | ||
|
||
- CF:`(unsigned) t < (unsigned) a` | ||
- ZF:`t == 0` | ||
- SF:`t < 0` | ||
- OF:`((a < 0 ) == (b < 0)) && ((a < 0) != (t < 0))` | ||
|
||
除了 `leaq` 指令类以外——因为 `leaq` 是用来完成地址计算的——所有操作都会**隐式的**设置操作码。对于逻辑操作而言,进位标志与溢出标志都会被设置成 `0`。对于移位操作,进位标志被设置成为最后一个被移出的位,溢出标志设置成 `0`. `inc` 和 `dec` 指令会会设置溢出标志和零标志,但是不会改变进位标志。 | ||
|
||
`cmp`和`test`指令类会设置条件码,但是不会改变目的寄存器的值。`cmp`指令会计算第二个操作数减去第一个操作数的结果,但是不会存储结果。`test`指令会计算两个操作数的按位与,但是不会存储结果。 | ||
|
||
### 3.6.2 Accessing the Conditional Codes | ||
|
||
条件码一般不会直接读取,常用的使用方法有三种: | ||
|
||
- 根据条件码的某种组合,将一个字节设置为 0 或者 1,这类指令就是 `set` 指令。 | ||
- 可以条件跳转到程序的某个其他的部分。 | ||
- 可以有条件地传送数据。 | ||
|
||
### 3.6.3 Jump Instructions | ||
|
||
`jmp` 指令会导致程序执行切换到程序中的一个全新的位置,这些跳转的目的地通常用一个标号来标识。`jmp` 指令可以是直接跳转,亦即跳转目标是作为指令的一部分编码的,直接在跳转指令后边跟上一个标号作为跳转目标;也可以是间接跳转,亦即跳转目标是从寄存器或者内存之中读出来的。我们还允许有条件的跳转,这就可以对程序进行控制。 | ||
|
||
### 3.6.4 Implementing Conditional Branches | ||
|
||
#### 3.6.4.1 Conditional Control | ||
|
||
#### 3.6.4.2 Conditional Move | ||
|
||
实现条件操作的传统方法就是通过使用**控制**的条件转移,当条件满足的时候,就沿着一条路径进行运行,不满足就使用另一种路径。这种策略简单而通用,但是在现代计算机上可能很低效,原因就是现代计算机使用**流水线/Pipelining**来获得高性能,流水线中,每条指令的处理都被分为了多个小阶段,每个阶段执行操作的一小个部分,通过重叠连续指令的方法来获得高性能,比如在取一条指令的同时,执行前面一条指令的算数运算。要做到这一点,就需要实现确定要执行的指令序列,这样才能保持整个流水线充满了指令,进而保持最优的性能。 | ||
|
||
一旦遇到条件跳转了(也就是分支),流水线处理器就会采用**分支预测**,猜测每条跳转指令是否会执行,猜对了还好,猜错了就会遇到招致很严重的惩罚,会浪费大约 15~30 个时钟周期,程序性能会大幅下降。为了减少这种性能损失,除了不断提升分支预测的正确率之外,现代处理器会使用**条件传送**指令,这种指令会根据条件码的值来决定是否传送数据,这样就可以避免分支预测错误的惩罚,并且极大避免随机情况下分支预测的错误。 | ||
|
||
但是条件传送也不总是好的,下面三种情况会让条件传送变得难办: | ||
|
||
- 两个计算都很难办,比如对于:`val = Test(x) ? Hard1(x) : Hard2(x);`,这样我们就要算两个很难算的东西,反而更加浪费时间; | ||
- 计算有可能出错,比如对于:`val = p ? *p : 0;`,这样就有可能会出现段错误; | ||
- 计算有副作用,比如对于:`val = x > 0 ? x*=7 : x+=13;`,这样算出来的结果就不对了。 | ||
|
||
所以我们的编译器(gcc)当分支的计算比较简单(至少多算一个花费的时间要比预测错误惩罚低)、比较安全并且没有副作用的时候,才会使用条件传送进行优化。 | ||
|
||
### 3.6.5 Loop | ||
|
||
??? info "Aside: Reverse engineer loops" | ||
|
||
|
||
|
||
### 3.6.6 Switch | ||
|
||
## 3.7 Procedures |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -325,5 +325,11 @@ if-else 必须在always块中使用,并且输出必须是reg类型。但是在 | |
|
||
endmodule | ||
``` | ||
=== "RTFSC" | ||
|
||
读源码,还没读,咕咕咕 | ||
|
||
## 7 计数器 & 定时器 | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters