《汇编语言》王爽–学习笔记
文章目录
一、基础知识
1. 基础概念
机器指令:CPU能直接识别并执行的二进制数字。
- 计算机将机器指令转变为一列高低电平,以使计算机的电子器件受到驱动,进行运算。
汇编指令:机器指令的助记符,同机器指令一一对应。
指令:指令通常由操作码和地址码(操作数)两部分组成
指令集:每种CPU都有自己的汇编指令集。
机器语言:机器指令的集合。
汇编语言由3类指令组成。
- 汇编指令
- 伪指令:没有对应的机器码,由编译器执行,计算机并不执行
- 其他符号:如+、-、*、/等,由编译器识别,没有对应的机器码。
编译器:能将汇编指令转换成机器指令的翻译程序。
在内存或磁盘上,指令和数据没有任何区别,都是二进制信息。
- 磁盘不同于内存,磁盘上的数据或程序如果不读到内存中,就无法被CPU使用。
2. 存储器
随机存储器(RAM)在程序的执行过程中可读可写,但必须带电存储,关机后存储的内容丢失。
只读存储器(ROM)在程序的执行过程中只读,关机后数据不丢失。
3. 三种外部总线
CPU要想进行数据的读写,必须和外部器件(芯片)进行以下三类信息的交互:
- 存储单元的地址(地址信息)
- 器件的选择,读或写的命令(控制信息)
- 读或写的数据(数据信息)
那CPU是通过什么将地址、数据和控制信息传到存储器芯片中的呢?
答:在计算机中专门有连接CPU和其他芯片的导线,通常称为总线 (物理上来讲,就是一根根导线的集合)
-
地址总线:CPU通过地址总线来指定存储单元的地址
一个CPU有N根地址线,则可以说这个CPU的地址总线宽度为N。这样的CPU最多可以寻找 2^n 个内存单元。
-
数据总线:数据总线的宽度决定了CPU和外界的数据传送速度。
8根数据总线一次可以传送一个8位二进制数据(即一个字节)。
-
控制总线:有多少根控制总线,就意味着CPU对外部器件提供多少种控制。
4. CPU对外设的控制
CPU对外设都不能直接控制,如显示器、音箱、打印机等。
直接控制这些设备进行工作的是插在扩展插槽上的接口卡。CPU可以直接控制这些接口卡,从而实现CPU对外设的间接控制。
如:CPU无法直接控制显示器,但CPU可以直接控制显卡,从而实现对显示器的间接控制。
5. 内存地址空间
CPU将系统中各类存储器看作一个逻辑存储器,这个逻辑存储器就是我们所说的内存地址空间。
CPU将各类存储器看作一个逻辑存储器:
我们在基于一个计算机硬件系统编程的时候,必须知道这个系统中的内存地址空间分配情况。因为当我们在某类存储器中读写数据的时候,必须知道它的第一个单元的地址和最后一个单元的地址,才能保证读写操作是在预期的存储器中进行。
二、寄存器
1. 寄存器
CPU由运算器、控制器、寄存器等器件构成,这些器件靠内部总线相连。
运算器进行信息处理;控制器控制各种器件进行工作;寄存器进行信息存储;内部总线连接各种器件,在它们之间进行数据的传送。
8086CPU为了兼容上一代的8位寄存器,AX,BX,CX,DX这四个寄存器可以拆开成两个 独立的 8位的寄存器来使用。分别为AH,AL, BH,BL, CH,CL, DH,DL。低八位(编号0-7)构成L寄存器,高八位构成H寄存器。
汇编指令或寄存器名称不区分大小写。
在进行数据传送或运算时,要注意指令的两个操作对象的位数应当是一致的。
2. 8086CPU 给出物理地址的方法
CPU通过地址总线送入存储器的,必须是一个内存单元的物理地址。
8086CPU采用一种在内部用两个16位地址合成的方法来形成一个20位的物理地址。
地址加法器采用 物理地址 = 段地址×16 + 偏移地址 的方法用段地址和偏移地址合成物理地址。
“段地址x16” 其实就是二进制数左移4位。
拓展:一个数据的十六进制形式左移1位,相当于乘以16;一个数据的十进制形式左移1位,相当于乘以10;一个X进制的数据左移1位,相当于乘以X。
3. 段寄存器
CS为代码段寄存器,IP为指令指针寄存器,它们的内容提供了CPU要执行指令的地址。
8086CPU的工作过程简要描述:
- 从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器;
- IP=IP+所读取指令的长度,从而指向下一条指令;
- 执行指令。转到步骤1,重复这个过程。
mov指令(传送指令)不能用于设置CS、IP的值,8086CPU提供转移指令修改CS、IP的内容。
- jmp 段地址:偏移地址:用指令中给出的段地址修改CS,偏移地址修改IP。如:
jmp 2AE3:3
- jmp 某一合法寄存器:用寄存器中的值修改IP。如:
jmp ax
,在含义上好似:mov IP,ax
4. 字
字单元:存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成。
对于字,只要在mov指令中给出16位的寄存器(如,用AX而不是AL/AH)就可以进行16位数据的传送。
5. DS 和 [address]
DS寄存器:存放要访问数据的段地址
[address]:表示一个偏移地址为address的内存单元(8086CPU自动取ds中的数据为内存单元的段地址)。
通过段地址和偏移地址即可定位内存单元。
6. 栈(SS和SP)
8086CPU提供入栈和出栈指令,即可以将一段内存当作栈来使用。
8086CPU的入栈和出栈操作都是以字为单位进行的!
问:CPU如何知道栈顶的位置?
答:8086CPU中由两个寄存器,段寄存器SS和寄存器SP,栈顶的段地址存放在SS中,偏移地址存放在SP中。任意时刻,SS:SP指向栈顶元素
入栈
push ax
表示将寄存器ax中的数据送入栈中,由两步完成。
- SP=SP-2,SS:SP指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶;
- 将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶。
入栈时,栈顶从高地址向低地址方向增长。
出栈
pop ax
表示从栈顶取出数据送入ax,由以下两步完成。
- 将SS:SP指向的内存单元处的数据送入ax中;
- SP=SP+2,SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。
8086CPU中没duan有记录栈顶上限和栈底的寄存器,因此需要程序员自己操心栈顶超界的问题。
CPU将内存中的某段内容当作 代码,是因 CS:IP
指向了那里;CPU将内存中的某段内容当作 栈,是因为 SS:SP
指向了那里。一定要弄清楚什么是我们的安排以及如何让CPU按照我们的安排行事。