> For the complete documentation index, see [llms.txt](https://lewiszlw.gitbook.io/notebooks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lewiszlw.gitbook.io/notebooks/blogs/history/hui-bian-yu-yan-cheng-xu-she-ji-ji-chu-zhi-shi.md).

# 汇编语言程序设计基础知识

## 进位记数制与不同基数的数之间的转换

### 二进制数

计算机为了便于存储及计算的物理实现，采用了二进制数。

二进制的基数为2，只有0,1两个数码，并遵循逢2进1的规则，它的各位权是以2的k次方表示的，因此二进制数$a\_{n}a\_{n-1}\cdots a\_{0};\cdot;b\_1b\_2\cdots b\_m$的值是：

$$a\_n\cdot2^n+a\_{n-1}\cdot2^{n-1}+\cdots+a\_0\cdot2^0+b\_1\cdot2^{-1}+b\_2\cdot2^{-2}+\cdots+b\_m\cdot2^{-m}$$ 为便于人们阅读及书写，经常使用**八进制数**或**十六进制数**（以$2^n$作为基数）来表示二进制数。它们的基数和数码如下：

| 进位记数制 | 基数 | 数码                              |
| ----- | -- | ------------------------------- |
| 十六进制  | 16 | 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F |
| 十进制   | 10 | 0,1,2,3,4,5,6,7,8,9             |
| 八进制   | 8  | 0,1,2,3,4,5,6,7                 |
| 二进制   | 2  | 0,1                             |

在计算机里，通常用数字后面跟一个英文字母来表示该数的数制。十进制数一般用D（decimal）、二进制数用B（binary）、八进制数用O（octal）、十六进制数用H（hexadecimal）来表示。例如：117D，111010B。也可以用这些字母的小写形式。

### 二进制数和十进制数之间的转换

#### 二进制数转换为十进制数

各位二进制数码乘以与其对应的权之和即为该二进制数相对应的十进制数。

#### 十进制数转换为二进制数

1. 降幂法 首先写出要转换的十进制数，其次写出所有小于该数的各位二进制权值，然后用要转换的十进制数减去与它最相近的二进制权值，如够减则减去并在相应位记以1；如不够减则在相应位记以0并跳过此位；如此不断反复，直到该数为0为止。
2. 除法 把要转换的十进制数的整数部分不断除以2，并记下余数，直到商为0为止。 对于被转换的十进制数的小数部分则应不断乘以2，并记下其整数部分，直到结果的小数部分为0为止。

### 十六进制数及其与二进制、十进制数之间的转换

#### 十六进制数的表示

计算机中存储信息的基本单位为一个二进制位（bit），它可以用来表示0和1两个数码。此外，由于计算机中常用的字符是采用由8位二进制数组成的一个**字节（byte）来表示的，因此字节也成为计算机中存储信息的单位。计算机的字长**一般都选为字节的整数倍，如16位、32位、64位等。一个字节由8位组成，它可以用两个**半字节**来表示，所以用十六进制数来表示二进制数是比较方便的。十六进制数的基数和二进制数的关系：

| 二进制数                | 十六进制数 |
| ------------------- | ----- |
| 0000                | 0     |
| 0001                | 1     |
| 0010                | 2     |
| 0011                | 3     |
| 0100                | 4     |
| 0101                | 5     |
| 0110                | 6     |
| 0111                | 7     |
| 1000                | 8     |
| 1001                | 9     |
| 1010                | A     |
| 1011                | B     |
| 1100                | C     |
| 1101                | D     |
| 1110                | E     |
| 1111                | F     |
| ### 十六进制数和二进制数之间的转换 |       |

* 由于十六进制数的基数是2的幂，所以这两种数制之间的转换是十分容易的。一个二进制数，只要把它从低位到高位每4位组成一组，直接用十六进制数来表示就可以了。 例如： 0011 0101 1011 1111 3 5 B F
* 反之，把十六进制数中的每一位用4位二进制数表示，就形成相应的二进制数了

#### 十六进制数和十进制数之间的转换

* 各位十六进制数与其对应权值的乘积之和即为与此十六进制数相对应的十进制数。
* 十进制数转换为十六进制数
  * 降幂法 首先写出要转换的十进制数，其次写出小于该数的各位十六进制权值，然后找出该数中包含多少个最接近他的权值的倍数，这一倍数即对应位的值，用原数减去此倍数与相应位权值的乘积得到一个差值，再用此差值去找低一位的权值的倍数，如此反复直到差值为0为止。
  * 除法 把要转换的十进制数的整数部分不断除以16，并记下余数，直到商为0为止。 对于被转换的十进制数的小数部分则应不断乘以16，并记下其整数部分，直到结果的小数部分为0为止。

## 二进制数和十六进制数运算

### 二进制数运算

* 加法规则 0+0=0 0+1=1 1+0=1 1+1=0（进位1）
* 乘法规则 0×0=0 0×1=0 1×0=0 1×1=1

### 十六进制数运算

* 十六进制加法 当两个一位数之和S小于16时，与十进制数同样处理；如果两个一位数之和大于或等于16时，则应该用S-16及进位1来取代S。
* 十六进制减法 与十进制数类似，够减时可直接相减，不够减时服从向高位借1位16的规则。
* 十六进制乘法 可以用十进制数的乘法规则来计算，但结果必须用十六进制数来表示。
* 十六进制除法 可以根据其乘法和减法规则处理。

十六进制数的运算可以采用先把该十六进制数转换为十进制数，经过计算后再把结果转换为十六进制数的方法。

## 计算机中数和字符的表示

### 数的补码表示

计算机中的数是用二进制来表示的，数的符号也是用二进制表示的。 在机器中，把一个数连同其符号在内数值化表示的数称为**机器数**。一般用最高有效位来表示数的符号，正数用0表示，负数用1表示。机器数可以用不同的码制来表示，常用的有原码、补码和反码表示法。多数机器的整数采用补码表示。

* 补码表示法中正数采用符号-绝对值表示，即数的最高有效位为0表示符号为正，数的其余部分则表示数的绝对值。 例如，假设机器字长为8，则$\[+1]\_补=00000001$，$\[+127]\_补=01111111$。
* 表示负数要麻烦一些。负数X用$2^n-|X|$来表示，其中n为机器的字长。另一种简单的方法：先求出该负数相对应的正数的补码表示，然后按位求反，末位加1。 例如，机器字长为8，$\[-127]\_补=2^8-127=10000001$。
* 补码表示法的符号扩展（如从8位扩展到16位），正数的符号扩展应该在前面补0，而负数的符号扩展应该在前面补1。
* n位补码表示的数的表数范围：$-2^{n-1}\leq N \leq 2^{n-1}-1$。

### 补码的加法和减法

对一个二进制数按位求反后在末位加1的运算称为求补运算，可以证明补码表示的数具有以下特性： $$\[X]\_补\overset{求补}{\Rightarrow}\[-X]\_补\overset{求补}{\Rightarrow}\[X]\_补$$

* 补码的加法规则 $$\[X+Y]\_补=\[X]\_补+\[Y]\_补$$
* 补码的减法规则 $$\[X-Y]\_补=\[X]\_补+\[-Y]\_补$$

### 无符号整数

在某些情况下，要处理的数全是正数，此时再保留符号位就没有任何意义了。我们可以把最高有效位也作为数值处理，这样的数称为无符号整数。在计算机中最常用的无符号整数是表示地址的数。

### 字符表示法

字符包括：

* 字母：A、B、...、Z，a、b、...、z；
* 数字：0、1、...、9；
* 专用字符：+、-、\*、/、↑、SP（space空格）...；
* 非打印字符：BEL（bell响铃）、LF（line feed换行）、CR（carriage return回车）、...

这些字符在机器里必须用二进制数来表示。80×86机采用目前最常用的美国信息交换标准码ASCII来表示。

## 几种基本的逻辑运算

### “与”运算

“与”运算又称逻辑乘，可用符号$\cdot$或$\bigwedge$来表示。如A、B两个逻辑变量的“与”运算结果：

| A | B | $A\bigwedge B$ |
| - | - | -------------- |
| 0 | 0 | 0              |
| 0 | 1 | 0              |
| 1 | 0 | 0              |
| 1 | 1 | 1              |

### “或”运算

“或”运算又称逻辑加，可用符号+或$\bigvee$来表示。“或”运算规则如下：

| A | B | $A\bigvee B$ |
| - | - | ------------ |
| 0 | 0 | 0            |
| 0 | 1 | 1            |
| 1 | 0 | 1            |
| 1 | 1 | 1            |

### “非”运算

“非”运算规则如下：

| A | $\overline A$ |
| - | ------------- |
| 0 | 1             |
| 1 | 0             |

### “异或”运算

“异或”运算可以用符号$\forall$来表示。运算规则如下：

| A | B | $A\forall B$ |
| - | - | ------------ |
| 0 | 0 | 0            |
| 0 | 1 | 1            |
| 1 | 0 | 1            |
| 1 | 1 | 0            |

**所有逻辑运算都是按位操作的。**

> 《IBM-PC汇编语言程序设计（第2版）》沈美明 温冬婵 著
