汇编语言
课程概要
人与人沟通需要使用到语言,人与计算机沟通也需要一种语言进行,你要跟计算机进行沟通,必须要使用计算机可以识别的语言,这种语言我们称之为机器语言,也就是0和1,二进制。
但对于人来说机器语言(二进制)比较难懂,所以前人就在这个基础上衍生出了 「汇编语言」 ,相比于机器语言,汇编语言更加通俗易懂一些,但汇编语言终究不是机器语言,想要计算机读懂汇编语言,就需要 「编译器」 来将汇编语言转为机器语言。
时代是在进步的,技术也是。伟大的前辈在基于 「汇编语言」 的基础上,又发明了一类语言,我们称之为 「高级语言」 ,例如C语言,其特点就是更加贴近人类的思维、表达方式,但与 「汇编语言」 一样的是: 「高级语言」也需要编译器将其转为计算机能读懂的机器语言。所以综上所述,不是语言变得强大了,而是编译器变得越来越强大。
学习 「汇编语言」 只是为了更好的去理解 「高级语言」 在计算机底层做了什么事情,更好的去理解计算机底层内容与 「高级语言」 的特性。
进制
前面,我们有提到计算机只可以读懂机器语言,那机器语言本身就是二进制,所以为了更好的了解、学习计算机,我们要深刻的去理解什么是进制。
如果你总是以十进制为基础去考虑其他进制,包括在进制运算时,也是先考虑转为十进制再运算,这说明你不理解进制的本质,想要真正的理解进制,就要忘掉我们生活中常用的十进制,也要忘掉进制间的转换。
进制的定义:N进制,由N个符号组成,逢N进1。那么问题来了,十进制是由十个符号组成,就一定是0、1、2、3、4、5、6、7、8、9么?其实并不是,我们既然说了是由符号组成,那么十进制也可以是由A、Y、B、3、4、5、D、9、0、X组成,由什么符号,取决于定义的那个人,我定义的十进制前20个表格是这样的:
| A | Y | B | 3 | 4 | 5 | D | 9 | 0 | X |
|---|---|---|---|---|---|---|---|---|---|
| YA | YY | YB | Y3 | Y4 | Y5 | YD | Y9 | Y0 | YX |
提问:1+1=3成立吗?
回答:在传统的十进制系统中,1+1 等于 2。然而,在自定义进制系统中,运算结果可以有不同的表现形式。例如,如果我们定义一个基于三个数字的进制系统,其中数字集合为 {1, 3, 9},那么在这个特定的进制系统中,我们可以规定 1 加 1 等于 3。这是因为进制系统的规则是由我们自行设定的,所以在这个自创的进制系统中,1+1=3 是合理的。
进制运算
基本了解进制后,我们需要了解进制间是如何运算的,八进制的10+4=?10-4=?10*4=?10/4=?首先,我们需要知道八进制的八个符号分别是什么,分别是:0、1、2、3、4、5、6、7。
那么如何计算呢?1. 写出八进制的前50 2. 借助算术表
八进制的前50表:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|
| 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
| 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
| 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
| 60 | 61 | 62 |
加法的本质实际上就是查表,10+4,就是从10这个数字开始依次往后查4位,那么其结果就是14。那么10-4就是依次向前查4位,104就等于10+10+10+10,那么是否等于从10这个数字开始依次往后查3个10位呢?其实并不是,因为这里是八进制,我们要严格按照八进制的表示来,这里的10(一零)实际上表示8个,也就是从10这个数字开始依次往后查3个8位,104的结果也就是40。
借助写表格的方式去查表计算,这并不高效,那么回想一下我们从学习数学开始是怎么学习计算的呢?相信你已经回忆起来了,我们是借助加减乘除这四张算术表去计算的,那么在这里我们可以尝试写一下八进制的加法算术表:
| 1+1 = 2 | ||||||
|---|---|---|---|---|---|---|
| 1+2 = 3 | 2+2 = 4 | |||||
| 1+3 = 4 | 2+3 = 5 | 3+3 = 6 | ||||
| 1+4 = 5 | 2+4 = 6 | 3+4 = 7 | 4+4 = 10 | |||
| 1+5 = 6 | 2+5 = 7 | 3+5 = 10 | 4+5 = 11 | 5+5 = 12 | ||
| 1+6 = 7 | 2+6 = 10 | 3+6 = 11 | 4+6 = 12 | 5+6 = 13 | 6+6 = 14 | |
| 1+7 = 10 | 2+7 = 11 | 3+7 = 12 | 4+7 = 13 | 5+7 = 14 | 6+7 = 15 | 7+7 = 16 |
这样再去计算八进制的算术题,就简单多了,其他进制运算以此类推。
二进制简写形式
在之前的课程概要中,我们说了计算机只能读懂机器语言(二进制),相信很多人就开始疑惑了,为什么计算机只能读懂二进制?原因是因为计算机是需要电的,而电路设计只有两种状态:1(真·通电)0(假·未通电),所以计算机中存储的任何文件、接收的任何指令都是由0和1组成的。
在这里,我们可以借助UltraEdit软件打开一个文件:
打开一看,为什么这里没有显示二进制0和1呢?是因为二进制使用、阅读都比较麻烦,所以如上图所示,展示出来的是十六进制,这里我们也可以称之为二进制的简写方式。
在计算机中二进制和十六进制的对应关系如下:
| 二进制 | 0 | 1 | 10 | 11 | 100 | 101 | 110 | 111 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 十六进制 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
这个对应关系表需要熟练掌握,做到看见二进制可以直接转为十六进制,反之亦然。
数据宽度
我们熟知的数字,也就是数学上的数字,理论来说只要你能写、纸张足够多,那么你是可以写任意大小数字的;但在计算机中,因为受到硬件的制约,数据是有长度限制的,我们一般称之为 「数据宽度」 ,超出最多宽度的数据会被丢弃掉。
数据宽度也有自己的单位:
| 名称 | 大小 |
|---|---|
| 位 (BIT) | █(1位) |
| 字节(Byte) | ████████(8位) |
| 字 (Word) | ████████████████(16位、2个字节) |
| 双字(Doubleword) | ████████████████████████████████(32位、2个字、4个字节) |
当我们存储数据的时候,需要知道自己存储的数据的数据宽度是什么,假设你要存储一个1,要存入字节中,那么以二进制的表示即为:0000 0001
在之前我们也说到二进制的简写形式就是十六进制,那么0000 0001转为十六进制即为0x01(0x开头表示这是一个十六进制,每4个0和1转为一个十六进制),那么字节(Byte) 的存储范围使用十六进制表示则为:0 - 0xFF,以此类推,字(Word) 的存储范围:0 - 0xFFFF,双字(Doubleword) 的存储范围:0 - 0xFFFFFFFF。
无符号数、有符号数
无符号数和有符号数,你不需要去弄清楚这两个名词的意思,只需要了解其不同点与相同点。
我们来举例说明二进制:0100 1000,它为无符号数编码规则是如何的?为有符号数呢?
| 无符号数 | 有符号数 |
|---|---|
| 0x48、72 | 0x48、72 |
直接转为十六进制与十进制,有无符号数都是一样的,但如果是1000 1000,其有无符号数的结果截然不同。
需要了解其不同之处,我们还要去了解原码、反码、补码的相关知识。
在这一节我们可以暂时得出结论:无符号数存储在计算机内就是其本身的值。
原码、反码、补码
上一章我们学习了无符号数和有符号数,但实际上我们只了解到无符号数存储的编码规则,对有符号数不了解,这一章来聊一下原码、反码、补码。
原码:最高位为符号位,其余各位为数值本身的绝对值
反码:正数反码与原码相同,负数符号位为1,其余位对原码取反
补码:正数补码与原码相同,负数符号位为1,其余位对原码取反加1
举例说明,我们分别以字节(Byte) 的形式将1、6、-1这三个有符号数存入计算机中,其二进制表示为?
1是一个正数,所以二进制原码、反码、补码都为:0000 0001;同理数字6也是如此。
-1是一个负数,我们知道有符号数最高位为符号位(最高位就是左边第一个数字),负数符号位为1,所以其二进制的原码为:1000 0001,但这是最终存入计算机中的二进制吗?并不是,在计算机中有符号数负数存储是以补码形式存储的:
通过原码:1000 0001,我们可以知道其反码为:1111 1110,补码(可以理解为在反码的基础上加一)为:1111 1111
计算机不会做加法
计算机只认识0和1,它能做的运算归根结底也就是对0和1进行运算,例如2+3、2-3,这种运算计算机是通过位运算去实现的,所以计算机本质上是不会做加法的。所以本章节主要是学习位运算:与、或、异或、非、左移、右移。
与运算:两个位都为1,结果才为1
或运算:只要有一个为1就为1
异或运算:不一样时则为1
非运算:0就是1、1就是0
左移:各二进制位全部左移若干位,高位丢弃,低位补0
右移:各二进制位全部右移若干位,低位丢弃,高位补0(shr)或补符号位(sar)
位运算加减乘除
计算机通过位运算实现加减乘除,而我们都知道所有算术都是通过加法演变的所有算术都是通过加法演变的,所以我们只需要明白计算机是如何通过加法计算的,其他就都明白了。
4+5的运算过程:
- 转为二进制:0000 0100、0000 0101
- 两者进行异或得出:0000 0001
- 判断是否存在进位(两者进行与运算):0000 0100,这里与运算结果不为0(二进制:0000 0000)则表示存在进位
- 继续进行异或:步骤二的结果与左移一位的步骤三结果 → 0000 0001 xor 0000 1000,得出:0000 1001
- 步骤四的结果还需要判断是否存在进位(与运算):步骤二的结果与左移一位的步骤三结果 → 0000 0001 and 0000 1000,得出:0000 0000,则表示不存在进位,步骤四的结果则为4+5的最后结果
- 二进制:0000 1001转为十进制:9