第1章 预备知识
第1章 预备知识
1.1 机器语言与汇编语言
1.1.1 机器语言
机器指令:操作码 + 地址码
指令的全体为计算机的指令系统
指令集合为机器语言
机器语言程序
1.1.2 汇编语言
助记符表示机器指令的操作码;用变量代替操作数的存放地址;在指令前冠以标号, 用来代表该指令的存放地址等。
指令助记符、语句标号、数据变量、伪指令及它们的使用规则构成了整个汇编语言的内容。
1.2 Intel系列机
1.2.1 Intel 80X86 微处理器简介
8086:16位CPU
80286:直接寻址16MB贮存,含有四个独立处理部件:执行部件、总线部件、指令部件和地址部件
提供两种工作方式:实地址方式和保护方式
1.2.2 Intel 80X86微处理结构
32位CPU分为六大部件:
- 总线接口部件
- 执行部件
- 指令预取部件
- 指令编译部件
- 分段部件
- 分页部件
1.总线接口部件
CPU与整个计算机系统之间的高速接口
接受总线请求,按有限权进行选择,最大限度利用本身资源位请求服务
2.执行部件
(1)数据寄存器组(EAX、EBX、ECX、EDX)
EAX(Accumulator):暂存
EBX(Base):
ECX(Count):标志循环次数上届
EDX(Data):保存操作数
(2)指示器编制寄存器组(ESI、EDI、ESP、EBP)
存放操作数的偏移地址,用作指示器或变址寄存器。
- ESP:堆栈指示器,栈顶指针
- EBP:基址寄存器,存放存储单元的偏移地址
- ESI和EDI:指示器、变址寄存器
- ESI用作取源操作数的指示器,源变址寄存器
- EDI用作送目的操作数的指示器,目的变址寄存器
3.指令预取部件和指令译码部件
- 指令预取部件:把将要执行的指令从主存之中取出,送入指令排队机构中排队(此处为复杂的排队系统)
- 指令译码部件:从预取指令队列中读出指令并译码,再送入译码指令队列排队供执行部件使用
独取指令时,用到很重要的寄存器——指令指示器
保存下一条将要被CPU执行的指令的偏移地址(EA)
16位代码段之中,指令指示器也为16位,称为IP,可以表示64k的偏移地址
32位代码段之中,EIP,表示4G的偏移地址
4.分段部件、分页部件
程序投入运行时,系统会为每个程序分配一片独立的虚拟内存空间
只有主存中的程序和数据才能够被访问,所以在执行某一程序或访问某一数据,必须要将其所在的虚拟空间映射到物理存储空间
32位CPU使用分段部件和分页部件实现这一映射
分段部件用于将各段二维的逻辑地址转换为一维的线性地址, 从而完成从虚拟空间到线性空间的转换, 实现系统与用户、用户与用户之间的隔离与共享。
分段部件有 6 个 16 位的段寄存器, 它们分别是:
CS———代码段寄存器;
SS———堆栈段寄存器;
DS———数据段寄存器;
ES、FS、GS———附加数据段寄存器。
实方式下,段的大小最大只能为64KB,取数据或指令的物理地址直接通过段寄存器的内容和EA生成
保护方式下,段大小可达4GB,这时的段寄存器内容称为选择符,通过该选择符找到描述符表,取出描述符后才能确定所需访问的段和存储单元
- 分段部件构造虚拟存储空间
- 分页部件则主要用于物理存储器的管理
1.2.3 80X86的3种工作方式
1.实地址方式
32位寄存器、32位操作数、32位寻址方式
32位CPU和16位CPU只能寻址1MB物理存储空间,程序段段大小不超过64KB
段基址和偏移地址都是32位(16位段)
2.保护方式
32位地址先,寻址4GB的物理存储空间,虚拟存储空看可达64TB
段基址和段内偏移量都是32位,程序段的大小可达4GB,这样的段也称为“32位”。
3.保护方式下的虚拟8086方式(V86方式)
保护方式下运行的类似实方式的工作环境
对于80X86中的32位CPU,在实方式下执行的是16位段的程序(寄存器和数据可以是 32/16位);在保护方式下可以对 32位段和 16位段的程序单独或混合操作;
虚 拟 8086方式可并行执行多个 8086的16位段程序,但由于它与实方式的特权级不同,因此,它还不能代替实方式。
1.3 主存储器和物地址的形成
1.3.1主存储器
存储器是用来存放程序和数据的装置
主存设在主机内部,用来存放当前运行的程序和所需的数据,一边随时像CPU高速提供信息
主存由许多存储位构成,这些储存位每8位组合成一个字节,
每相邻的2个字节又可以组成一个字,
相邻的2个字有可以组成一个双字。
区分不同字节存储单元:
物理地址(PA):
每一单元被指定一个编号,用以区分不同字节存储单元。
80X86机的主存是按8位字节编址的,即以字节为最小寻址单位。
字由相邻两个字节组成,规定字地址由2个字节中较小的确定
双字地址由4个字节的最低地址确定
存放在主存中的程序和数据一般均按物理地址存取
字数据低8位存放在低地址字节中,高8位存放在相邻的高地址字节中;双字数据存放是低16位存放在低地址字中,高16位存放在相邻的高地址字中。
1.3.2 堆栈
先进后出原则,进栈为“压入”,出栈为“弹出”。
堆栈由一片存储单元和一个指示器组成,固定端叫做栈底
- 栈指针:用来指示栈元素进栈和出栈时偏移地址的变化
- 栈顶:指针所指示的最后存入数据的单元
1.进栈指令PUSH
语句格式:PUSH OPS
功能:将立即数或寄存器、段寄存、存储器中的一个字/双字数据压入堆栈中
1 |
|
2.出栈指令POP
语句格式:POP OPD
功能:将栈顶元素弹出送至某一寄存器、段寄存器或存储器中。
1 |
|
除了PUSH和POP指令外,如果其他指令要访问堆栈,也可以通过基址寄存器BP进行
注意:
- 当堆栈段为16位段时,系统自动使用SP作栈指针;32位,使用ESP
- 进栈或出栈操作时,栈指针(SP/ESP)移动的字节数取决于操作数的类型。字操作,(SP/ESP)均是±2,双字操作,(SP/ESP)均为±4
3.将8个寄存器内容顺序入栈指令
该指令分为8个16位寄存器入栈和对8个32位寄存器入栈
(1)将8个16位寄存器入栈
语句格式:PUSHA
功能:将8个16位寄存器按AX、CX、DX、BX、SP、BP、SI、DI顺序入栈保存
1.3.3 物理地址的形成
80X86机,最低档CPU为8086,20根地址线,寻址能力为$2^{20}B$,主内存容量为1MB,物理地址编号从0~0FFFFFH。
此时CPU与存储器交换信息必须要20位的物理地址,但是8086内部为16位结构,寄存器也是16位的。
16位寄存器进行地址运算,表示16位地址,操作数范围最大为64KB。
主存分段使用方案:
将1MB的存储器按64KB分段,设置4个段寄存器CS、DS、SS、ES,保存当前可使用段的段首址。
段首址从刚好被16整除的地址开始,低四位均为0,忽略这些0,刚好16位可以存入段寄存器之中,然后操作时,内容左移4位,补上4个0,再加上某待访问存储单元的偏移地址,获得20位物理地址。
存储单元的地址由两部分组成:段首地址:偏移地址,被称为二维的逻辑地址
1. 实方式物理地址的形成
实方式情况下,32位CPU只能寻址1MB的物理存储空间,采用分段使用的方式,每段大小不超过64KB,段首地址和段内偏移地址都用16位表示。
在每一给定时刻,CPU可以在不修改段寄存器内容的情况下访问6个段:
- 代码段
- 堆栈段
- 数据段
- 3个附加数据段
这些当前能被CPU访问段的首地址由分段部件中的6个专用段寄存器给出
- CS:给出当前代码段首地址(取指令指针为IP)
- SS:给出当前堆栈段首地址(取栈指针为SP)
- DS:给出当前数据段首地址
- ES、FS、GS:给出当前附加数据段首地址
- 代码段是程序代码的存储区,指令指示器IP总是保存着下一条将要取出指令相对于CS的偏移地址在代码段中取指令时,指令物理地址:
$PA = (CS)_{左移4位}+(IP)$
堆栈段时程序的临时数据存储区,存放暂时无用的数据。用户自定义堆栈段,作子程序调用、系统功能调用、中断处理等操作。系统以SP为指针,做堆栈操作时,栈顶物理地址:
$PA = (SS)_{左移4位}+(SP)$
数据段和附加数据段是程序使用时的数据存储区。附加数据段和数据段重合,设置成一个段,数据的物理地址:
$PA = (DS或ES、FS、GS)_{左移4位}+16位偏移地址$
说明:
程序大小可以自定,但是必须要小于或等于64KB,每个段在主存的具体位置由操作系统分配
分段不唯一,某一片具体存储单元,可以属于一个段,也可以属于多个段
- 汇编源程序之中,用户必须将数据段首址置入DS、ES、FS、GS,而CS、SS由系统自动录入
2.保护方式下物理地址的形成
保护方式,使用32根地址线,可以寻址4GB物理存储空间,程序大小也可达到4GB,段基址和段内偏移地址都为32位。
多任务机制:对虚拟存储空间的任务进入主存进行合理调度和分配,实施执行环境的隔离和保护。
(1) 特权级
(2) 描述符
除了段基址以外,其余信息被整合到一起,用4个字来描述,被称为描述符
按不同的描述对象,可分为:
- 存储段描述符
- 系统段描述符
- 控制描述符
描述符通用结构
32位段基址(不分页,该基地址为段在主存的起始物理地址)
20位段界限(段长度)
第三个字的高字节描述了段的性质及当前使用情况
P:存在为,P=1,描述符对应段存在,P=0,不存在
DPL:描述符对应段的特权级
S:段类型,S=1,存储段描述符(程序代码段、数据段),S=0,存储系统描述符
TYPE:段的具体属性,共有三位。对存储段来说, 第 11位E描述了该段是否为可执行段。 E =0 说明该段为不可执行段, 即为数据段或堆栈段;E =1 说明该段为可执行段, 即为代码段。
在两种不同类型的段中, 另两位(第 10 ~9 位)所描述的内容是不同的
A:已访问位
第四个字7~4描述信息
- G:粒度位 G =0 时说明段长度的计量单位为字节(B);G =1 时说明段长度的计量单位为页, 1 页为 4KB。
- D:D=0,16位操作数和16位有效地址,堆栈使用SP作指针,界限值0FFFFH;D=1,32位操作数和32位有效地址, 堆栈使用ESP指针,界限值0FFFFFFFFH。剩余两位为保留位和系统专用位。
(3)描述符表
- 局部描述符表
- 全局描述符表
- 中断描述符表
(4)段选择符和描述符寄存器
保护方式下,段寄存器不保存段的开始地址,从描述符表中选择相应段的描述符的方式。
段选择符
(5)保护方式下物理地址的形成
- 根据段寄存器中的描述符索引值、TI及RPL值,从描述符表中选出描述符,然后判断是否有溢出,进行特权级、使用合法性及各种相关属性检查,合格之后送入对应描述符高速缓冲寄存器。
- 需要对该段存储空间访问时,从描述符高速缓冲寄存器中取出段基址,与存放于EIP/ESP或某一指示器中的偏移地址相加,形成32位线性地址。
- 不分页,则得到物理地址;分页的话,经过分页部件映射,将线性地址转换为物理地址。
1.4数据在计算机内的表示形式
- 二进制
- 字节
- 字
- 双字
- 三字
- 四字
- 十字
- 八进制
- 十六进制
- BCD码
1.4.1 数值数据在计算机内的表示形式
- 定点表示法
- 浮点表示法
有符号数一律采用二进制补码
计算机在进行算术逻辑运算时, 总是把参与运算的、用补码表示的操作数作为无符号数处理, 这时, 数的表示范围则与前面讨论的完全不同。
1.4.2 BCD码
利用4位二进制表示十进制数
BCD码:
未压缩的BCD码
- 每个字节只放一个十进制位数
压缩的BCD码
- 一个字节存放两个十进制位数
1.4.3 字符数据在机内的表示形式
$ASCII$码标准
1.5 标志寄存器
标志寄存器:保存在一条指令执行之后, CPU 所处状态的信息及运算结果的特征。
16位CPU中的标志寄存器是16位的,称为FLAGS,32位CPU中的标志寄存器是32位的,称EFLAGS
32位向下兼容
1.5.1 标志位
常用标志位:
- 条件标志位
- 控制标志位
- 32位寄存器扩充的系统标志位
1.条件标志位
由CPU根据执行完一条指令后所得运算结果的特征自动设置的,主要用作控制条件转移指令是否转移的条件。
- 符号标志SF(第7位)
- 零标志符ZF(第6位)
- 溢出标志OF(第11位)
- 进位标志CF(第0位)
- 辅助进位标志AF(第4位)
- 奇偶标志位PF(第2位)
2.控制标志位
- 方向标志DF
- 中断允许标志IF
- 跟踪标志TF
3.32 位标志寄存器扩充的系统标志位
- IO 特权标志 IOPL
- 占两位,指定了要求执行I/O指令的特权级
- 嵌套任务标志 NT
- 控制中断返回指令的执行
- 恢复标志RF
- 与寄存器一起使用,确定是否接受调试故障
- 虚拟8086方式标志VM
- VM置1,CPU在虚拟8086方式下工作,置0,保护方式下工作
1.5.2标志寄存器操作指令
1.标志寄存器传送指令
(1)LAHF
功能:将标志寄存器低8位存入AH中,即$(EFALGS){7~0} \rightarrow AH$
(2)SAHF
功能:将AH中的内容送入标志寄存器的低8位之中,高位保持不变。
2.32位标志寄存器进栈指令PUSHFD
功能:将标志寄存器的内容压入堆栈之中
$(EFLAGS)\rightarrow \downarrow(ESP/SP) $
3.32位标志寄存器出栈指令POPFD
功能:$\uparrow(ESP/SP)\rightarrow EFLAGS$
说明:该指令不影响标志位RF、VM、IOPL、VIF、VIP和未定义位。