一、汇编与高级语言对比
1 区别
- 汇编语言与机器语言一一对应,每一条机器指令都有与之对应的汇编指令
- 汇编语言可以通过编译得到机器语言,机器语言可以通过反汇编得到汇编语言
- 高级语言可以通过编译得到汇编语言\机器语言,但汇编语言\机器语言几乎不可能还原成高级语言
2 高级语言反编译表现
3 汇编语言的特点
- 可以直接访问、控制各种硬件设备,比如存储器、CPU等,能最大限度地发挥硬件的功能
- 汇编指令是机器指令的助记符,同机器指令一一对应。每一种CPU都有自己的机器指令集\汇编指令集,所以汇编语言不具备可移植性
- 知识点过多,开发者需要对CPU等硬件结构有所了解,不易于编写、调试、维护
- 不区分大小写,比如mov和MOV是一样的
4 编译阶段比较
- 采用高级语言C++和汇编语言编写同一个功能
将a+b的结果赋值给c,然后在屏幕上打印c的结果
二、汇编语言的种类
- 目前讨论比较多的汇编语言有
- 8086汇编(8086处理器是16bit的CPU)
- Win32汇编
- Win64汇编
- AT&T汇编(Mac、iOS模拟器)
- ARM汇编(嵌入式、iOS设备)
......
- 入门建议先从学些8086汇编开始
结构简洁、经典
参考书籍:王爽《汇编语言》
三、软件\程序的执行过程
- 最为关键的是需要了解CPU和内存
- 在学习汇编语言过程中,遇到的绝大部分指令都是跟内存、CPU有关的
四、总线
1. 总线概念及分类
-
总线:一根根导线的集合
-
每一个CPU芯片都有许多管脚,这些管脚和总线相连,CPU通过总线跟外部器件进行交互
-
总线的分类
1 地址总线、数据总线、控制总线
2. CPU从内存的3号单元读取数据
3. 数据总线
- 8088的数据总线宽度是8,8086的数据总线宽度是16,分别向内存中写入89D8H
- 89D8H,是16进制数,每个数字代表4bit,因为2的4次方=16,2个16进制数代表一个字节bytes,因为1B = 8bit。所以89D8H表示2个字节,89一个字节,D8一个字节
-
1B = 8bit; 2^10B = 1kB; 2^20B = 1MB; 2^30B = 1GB; 2^40B = 1TB;
五、内存
1. 各类存储器的逻辑连接情况
2. 内存地址及区域划分
3. 各类存储器的逻辑连接-物理地址对应图
六、8086的寻址方式
- CPU访问内存单元时,要给出内存单元的地址
- 8086有20位地址总线,可以传送20位的地址,1M的寻址能力
- 但它又是16位结构的CPU,它内部能够一次性处理、传输、暂时存储的地址为16位。如果将地址从内部简单地发出,那么它只能送出16位的地址,表现出来的寻址能力只有64KB
1. 20位物理地址生成原理
8086采用一种在内部用2个16位地址合成的方法来生成1个20位的物理地址
七、内存的分段管理
- 8086是用“起始地址(段地址×16) + 偏移地址 = 物理地址”的方式给出物理地址
- 为了开发方便,我们可以采取分段的方法来管理内存,比如:
- 地址10000H~100FFH的内存单元组成一个段,该段的起始地址为10000H,段地址为1000H,大小为100H
- 地址10000H1007FH、10080H100FFH的内存单元组成2个段,它们的起始地址为:10000H和10080H,段地址为1000H和1008H,大小都为80H
1. 寻址能力计算
偏移地址为16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB
八、寄存器
1. CPU的典型构成
2. 寄存器
- 对程序员来说,CPU中最主要部件是寄存器,可以通过改变寄存器的内容来实现对CPU的控制
- 不同的CPU,寄存器的个数、结构是不相同的(8086是16位结构的CPU)
- 8086有14个寄存器
- 都是16位的寄存器
- 可以存放2个字节
3. 通用寄存器
- AX、BX、CX、DX这4个寄存器通常用来存放一般性的数据,称为通用寄存器(有时也有特定用途)
- 通常,CPU会先将内存中的数据存储到通用寄存器中,然后再对通用寄存器中的数据进行运算
- 假设内存中有块红色内存空间的值是3,现在想把它的值加1,并将结果存储到蓝色内存空间
- CPU首先会将红色内存空间的值放到AX寄存器中:
mov ax,红色内存空间
- 然后让AX寄存器与1相加:
add ax,1
- 最后将值赋值给内存空间:
mov 蓝色内存空间,ax
4. 通用寄存器分类
-
AX、BX、CX、DX这4个通用寄存器都是16位的,如下图所示
上一代8086的寄存器都是8位的,为了保证兼容, AX、BX、CX、DX都可分为2个独立的8位寄存器来使用
-
H
代表高位寄存器 -
L
代表低位寄存器
九、字节与字
- 在汇编的数据存储中,有2个比较常用的单位
-
字节
:byte,1个字节由8bit组成,可以存储在8位寄存器中 -
字
:word,1个字由2个字节组成,这2个字节分别称为字的高字节和低字节
-
比如数据20000(4E20H,0100111000100000B),高字节的值是78,低字节的值是32
1个字可以存在1个16位寄存器中,这个字的高字节、低字节分别存储在这个寄存器的高8位寄存器、低8位寄存器中
十、段寄存器
- 8086在访问内存时要由相关部件提供内存单元的段地址和偏移地址,送入地址加法器合成物理地址
- 是什么部件提供段地址?段地址在8086的段寄存器中存放
- 8086有4个段寄存器:CS、DS、SS、ES,当CPU需要访问内存时由这4个段寄存器提供内存单元的段地址
- CS (Code Segment):代码段寄存器
- DS (Data Segment):数据段寄存器
- SS (Stack Segment):堆栈段寄存器
- ES (Extra Segment):附加段寄存器
每个段寄存器的具体作用是?
1. CS和IP
- CS为代码段寄存器,IP为指令指针寄存器,它们指示了CPU当前要读取指令的地址
-
任意时刻,8086CPU都会将CS:IP指向的指令作为下一条需要取出执行的指令
2. 指令的执行过程
十一、指令和数据
在内存或者磁盘上,指令和数据没有任何区别,都是二进制信息
-
CPU在工作的时候把有的信息看做指令,有的信息看做数据,为同样的信息赋予了不同的意义
CPU根据什么将内存中的信息看做指令?
- CPU将CS:IP指向的内存单元的内容看做指令
- 如果内存中的某段内容曾被CPU执行过,那么它所在的内存单元必然被CS:IP指向过
1. jmp指令
- CPU从何处执行指令是由CS、IP中的内容决定的,我们可以通过改变CS、IP的内容来控制CPU执行目标指令
- 8086提供了一个mov指令(传送指令),可以用来修改大部分寄存器的值,比如
mov ax,10、mov bx,20、mov cx,30、mov dx,40 - 但是,mov指令不能用于设置CS、IP的值,8086没有提供这样的功能
-
8086提供了另外的指令来修改CS、IP的值,这些指令统称为转移指令,最简单的是jmp指令