第1章、基础知识
1.1 机器语言
机器语言是机器指令的集合。机器指令是一台机器可以正确执行的命令。电子计算机的机器指令是一列二进制数字。计算机将之转变为一列高低电平,以使计算机的电子器件受到驱动,进行运算。
每一种微处理器(cpu),由于硬件设计和内部结构的不同,就需要用不同的电平脉冲来控制,使它工作。所以每一种微处理器都有自己的机器指令集,也就是机器语言。
每一种CPU也都有自己的汇编指令集。
1.2 汇编语言的产生
汇编语言的主体是汇编指令,即机器指令便于记忆的书写格式
汇编编译器将程序员写出的汇编代码编译成机器语言,由计算机最终执行。
1.3 汇编语言的组成
1.4 存储器
CPU控制计算机的运作和运算,向CPU提供指令和数据使它工作,指令和数据存放在存储器中,即内存。程序放在磁盘中,磁盘中的程序和数据只有先读到内存中,才能被CPU使用。
CPU可以直接使用的信息在存储器中存放。
1.5 指令和数据
指令和数据是应用上的概念,在内存和磁盘上,指令和数据没有任何区别,都是二进制信息。
1.7 CPU对存储器的读写
CPU要从内存中读数据,首先要指定存储单元的地址,
还要指明对哪一个器件进行操作,
以及进行什么操作,是从中读数据,还是从中写数据。
因此,CPU要想进行数据的读写,必须和外部器件(芯片)进行以下3类信息的交互:
- 存储单元的地址(地址信息);
- 器件的选择,读或写的命令(控制信息);
- 读或写的数据(数据信息)。
连接CPU和其他芯片的导线的集合称为总线,CPU通过总线将三种信息传到其他芯片中。
对应传递三种信息,总线分为:
- 地址总线
- 控制总线
- 数据总线
CPU从3号单元中读取数据的过程如下:
1.8 地址总线
CPU通过地址总线来指定存储器单元。
一个CPU有N根地址线,则这个CPU的地址总线的宽度为N。这样的CPU最多可以寻找2的N次方个内存单元(一个内存单元就是一字节)。
地址总线的宽度决定了CPU的寻址能力。
1.9 数据总线
CPU通过数据总线与内存或其他器件之间进行数据传递。
数据总线的宽度决定了CPU和外界的数据传递速度(一次数据传送量)。
1.10 控制总线
CPU通过控制总线对外部器件进行控制。
控制总线的宽度决定了CPU对外部器件的控制能力。
1.11 CPU对其他器件和外部设备的控制
每一台PC中,都有一个主板,总线就印刷在主板上,主板上有核心器件和一些主要器件(如CPU、存储器、外围芯片组、扩展插槽(RAM内存条和各类接口卡)),这些器件通过总线相连。
CPU只能直接控制主板上的这些器件,不能直接控制外部设备(如显示器、音响、打印机)。CPU只能通过总线直接控制主板上的扩展插槽,和插在扩展插槽上的接口卡,接口卡再控制外部设备,从而实现CPU对外部设备的间接控制。
1.12 各类存储器芯片
随机存储器(RAM)在程序的执行过程中可读可写,必须带电存储
只读存储器(ROM)在程序的执行过程中只读,关机数据不丢失
PC中的存储器从功能和连接上又分为以下几类:
-
随机存储器
用于存放供CPU使用的绝大部分程序和数据,主随机存储器一般由两个位置上的RAM组成,装在主板上RAM和插在扩展插槽上的RAM(内存条)。
-
装有BIOS的ROM
BIOS(Basic Input/Output System,基本输入输出系统)是各类接口卡(显卡网卡)厂商提供的软件系统,作用是:通过它对硬件设备(如显示屏)进行输入输出。所以使用只读存储器(ROM)来存储BIOS。在主板和某些接口卡上插有存储相应BIOS的ROM。
-
接口卡上的RAM
某些接口卡需要对大批量输入、输出数据进行暂时存储,在其上装有RAM。最典型的是显示卡一上的RAM,一般称为显存。显示卡随时将显存中的数据向显示器上输出。换句话说,我们将需要显示的内容写入显存,就会出现在显示器上。
接口卡上一般同时需要RAM和ROM
- ROM用来存储BIOS,来对硬件设备进行输入输出,同时为了防止CPU对BIOS进行修改,用ROM来存储。
- RAM用来暂时存储输入输出数据。
1.13 内存地址空间
CPU在操控主板上的存储器的时候,把它们都当作内存来对待,把它们总的看作一个由若干存储单元组成的逻辑存储器(即虚拟内存空间),这个逻辑存储器就是我们所说的内存地址空间。
所有的物理存储器被看作一个由若干存储单元组成的逻辑存储器,这个逻辑存储器在物理上是不存在的,是一个虚拟的内存空间,相当于CPU给每个物理存储器在这个虚拟内存空间中划分了一个地址段,即一段地址空间,方便CPU对不同的物理存储器进行读写。CPU在这段地址空间中读写数据,实际上就是在相对应的物理存储器中读写数据。
内存地址空间的大小受CPU地址总线宽度的限制,80386CPU 的地址总线宽度为32,则内存地址空间最大为4GB。
在基于一个计算机硬件系统编程的时候,必须知道这个系统中的内存地址空间分配情况。因为当我们想在某类存储器中读写数据的时候,必须知道它的第一个单元的地址和最后一个单元的地址,才能保证读写操作是在预期的存储器中进行。比如,我们希望向显示器输出一段信息,那么必须将这段信息写到显存中,显卡才能将它输出到显示器上。要向显存中写入数据,必须知道显存在内存地址空间中的地址。
第2章、寄存器
CPU由运算器、控制器、寄存器构成。
总线相对于CPU又分为外部总线和内部总线,内部总线连接CPU内部的各个器件,外部总线连接CPU和主板上的其他器件。
- 运算器进行信息处理;
- 寄存器进行信息存储;
- 控制器控制各种器件进行工作;
- 内部总线连接各种器件,在它们之间进行数据的传送。
不同的CPU,寄存器的个数、结构是不相同的。8086CPU 有14个寄存器: AX、BX、CX、DX、SI、 DI、SP、BP、IP、CS、SS、DS、ES、PSW,都是16位的。
2.1 通用寄存器
AX、BX、CX、DX这4个寄存器通常用来存放一般性的数据,被称为通用寄存器。
为了保证兼容,AX、BX、CX、DX都可以分为两个独立的8位寄存器使用:
16位 | 8高位 | 8低位 |
---|---|---|
AX | AH | AL |
BX | BH | BL |
CX | CH | CL |
DX | DH | DL |
8086CPU可以一次性处理以下两种尺寸的数据。
- 字节:记为byte,一个字节由8个bit组成,可以存在8位寄存器中。
- 字:记为word,一个字由两个字节组成,可以存在一个16位寄存器中(16位CPU)
8086采用小端模式:高地址存放高位字节,低地址存放低位字节。
2.3 汇编指令
注意,此时al是作为一个独立的8位寄存器来使用的,和ah没有关系,CPU在执行这条指令时认为ah 和al是两个不相关的寄存器。不要错误地认为,诸如add al,93H的指令产生的进位会存储在ah中,add al,93H进行的是8位运算。
在进行数据传送或运算时,指令的两个操作对象的位数必须一致!
2.4 8086CPU给出物理地址的方法
CPU访问内存单元时,要给出内存单元的地址。所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,称为物理地址。
8086CPU是16位结构的CPU,即:
- 运算器一次最多可以处理16位的数据;
- 寄存器的最大宽度为16 位;
- 寄存器和运算器之间的通路为16 位。
内存单元的地址在送上地址总线之前,必须在CPU中处理、传输、暂时存放
8086CPU是16位结构,在内部一次性处理、传输、暂时存储的地址为16位,但是却有20位地址总线,可以传送20位地址,达到1MB寻址能力。
从8086CPU的内部结构来看,如果将地址从内部简单地发出,那么它只能送出16位的地址,表现出的寻址能力只有64KB。
8086CPU采用一种在内部用两个16位地址合成的方法来形成一个20位的物理地址。
当8086CPU要读写内存时:
- CPU中的相关部件提供两个16位的地址,一个称为段地址,另一个称为偏移地址;
- 地址加法器将两个16位地址合成为一个20位的物理地址;
地址加法器采用物理地址 = 段地址×16 + 偏移地址的方法用段地址和偏移地址合成物理地址。
2.8 段的概念
内存并没有分段,段的划分来自于CPU(类似于内存地址空间,段也是一个虚拟的概念)。
我们可以将若干地址连续、起始地址为16的倍数的一组内存单元定义为一个段。用段地址x16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。
有两点需要注意:段地址x16必然是16的倍数,所以一个段的起始地址也一定是16的倍数;偏移地址为16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB。
2.9 段寄存器
段寄存器:8086CPU有4个段寄存器:CS、DS、SS、ES
,提供内存单元的段地址。
1、CS和IP
CS为代码段寄存器,IP为指令指针寄存器
CPU将CS、IP中的内容当作指令的段地址和偏移地址,用它们合成指令的物理地址
在任意时刻,CPU将CS:IP指向的内容当作指令执行
8086CPU的工作过程简要描述
- 从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器;
- IP=IP+所读取指令的长度,从而指向下一条指令;
- 执行指令。转到步骤1,重复这个过程。
在8086CPU加电启动或复位后(即CPU刚开始工作时)CS和IP被设置为CS=FFFFH,IP=0000H,即在8086PC机刚启动时,FFFF0H单元中的指令是8086PC机开机后执行的第一条指令。
CPU只认CS:IP指向的内存单元中的内容为指令,一段代码存放在123B0H~123B9H 内存单元中,将其定义为代码段,如果要让这段代码得到执行,可设CS=123BH、 IP=0000H。
2、修改CS、IP的指令
8086CPU大部分寄存器的值,都可以用mov指令修改,mov指令被称为传送指令。
但是,mov指令不能设置CS、IP的值。
8086CPU使用jmp指令修改CS、IP的值,能修改CS、IP的值的指令被称为转移指令。
- jmp 段地址:偏移地址:用指令中给出的段地址修改CS,偏移地址修改IP。如:
jmp 2AE3:3
- jmp 某一合法寄存器:仅修改IP的内容。如:
jmp ax
。在含义上好似:mov IP,ax
8086CPU不支持将数据直接送入段寄存器的操作。
实验 1 查看CPU和内存,用机器指令和汇编指令编程
Debug的使用
-
用R命令查看、改变CPU寄存器的内容;
-
查看寄存器的内容:
在所有寄存器的下方,还列出了CS:IP所指向的内存单元的地址,机器码,并将它翻译成汇编指令
-
改变寄存器的内容:
在r命令后加寄存器名来改变寄存器的内容
-
-
用D命令查看内存中的内容:
用“d 段地址:偏移地址”的格式来查看指定内存中的内容,debug将列出从指定内存单元开始的128个内存单元的内容
最右侧是每个内存单元中的数据对应的ASCII码字符。
一进入Debug后,用D命令直接查看,将列出Debug预设的地址处的内容。
在使用“d段地址:偏移地址”之后,接着使用D命令,可列出后续的内容。
可以指定D命令的查看范围,此时采用“d 段地址:起始偏移地址 结尾偏移地址”的格式。比如要看1000:0~1000:9中的内容,可以用“d 1000:09”实现。
-
如果我们只想查看某一个内存单元的内容
-
用E命令改写内存中的内容:
- 可用“e 起始地址 数据 数据 数据…”的格式进行
-
也可以用提问的方式一个一个的改写
用U命令将内存中的机器指令翻译成汇编指令;
-
用T命令执行一条机器指令;
t命令只会执行CS:IP指向的指令,所以在执行前需要用r命令改写CS:IP中的内容,使其指向我们想要执行的指令。
-
用A命令以汇编指令的格式在内存中写入一条机器指令
使用a命令,从预设的地址开始输入指令(可以自己给定地址)
输入一条指令后,按下回车,IP会自动指向下一个内存单元。
什么都不输入直接按回车表示结束。