微机概述

微机发展概况

微机发展

  • 1946年美国宾夕法尼亚大学为了弹道设计的需要设计了世界上第一台数字电子计算机ENIAC。
  • 1971年,Intel研究制造了I4004微处理器芯片。该芯片可同时处理4位二进制数,集成2300个晶体管,每秒6万次,约200美元。它是世界上第一个以它为核心的微处理器芯片MCS-计算机标志着世界上第一台微型计算机的诞生。

微机相关概念

  • 什么是微机?
    微机是以大规模、超大规模的微处理器为核心,配备存储器、输入/输出接口电路和系统总线。
  • 分阶段标志: 字长微处理器型号
  • 微机开发的特点
    • 速度 越来越快
    • 容量 越来越大
    • 功能 越来越强
  • 在微机的发展过程中,最成功、最有影响力的是IBM PC系列微机
  • 微机系统结构:
    冯.诺依曼建立的存储程序概念-冯.诺依曼结构
    • 冯·诺依曼结构,又称普林斯顿结构,是一种将程序指令存储器和数据存储器结合在一起的存储器结构。程序指令存储地址和数据存储地址指向同一存储器的不同物理位置,因此程序指令和数据的宽度相同,如英特尔8086中央处理器的程序指令和数据为16位宽。
    • 数学家冯·诺依曼提出了计算机制造的三个基本原则,即采用二进制逻辑程序存储执行以及计算机由五算器、控制器、存储器、输入设备、输出设备五部分组成,这种理论叫冯·诺依曼系统结构。(来源维基百科)

微机分层存储系统

存储器可分为五层:
  • 0层通常是CPU内部寄存器,离开CPU最近,访问速度很快,但数量有限.
  • 一层存储器是高速缓冲存储器Cache
  • 两层是主存储器,通常是动态的RAM(DRAM)组成
  • 三层是大容量虚拟存储器(磁盘存储器)
  • 四层是外存储器(光存储介质等)

开发软件系统

常见操作系统:
  • DOS
  • Windows
  • Linux
  • UNIX/Xenix
  • OS/2
  • Netware

单片机

单片机是把CPU、一定容量的存储器和必要的I/O具有计算机完整功能的微机集成在芯片上。

微机的应用

1.工业控制
2.事物处理
3.计算机辅助设计和辅助制造(CAD/CAM)
4.教学培训
5.家庭娱乐和家政管理
6.科学与工程计算
7.人工智能

计算机中数的表示和编码

计算机中的进位计数制

表示进位计数系统

十进制表示法

十进制数为0,1,2,…,8、90个不同的符号来表示值,它采用了逢十进一,借一当十的原则。

二进制表示法

基数为10的记数制称为十进制;基数为2的记数制称为二进制。
二进制数的计算规则是逢二进一,借一当二。

八进制表示法

八进制数是基数为八的计数制。八进制数主要为0,1,2,…,这八个阿拉伯数字。
八进制数的运算规则是逢八进一,借一当八。
八进制表示数值方法如下:
例:$$(467.6)_0=4 \times 8^2 6 \times 8^1 7 \times 8^0 6 \times 8^{-1}$$

十六进制表示法

基数为16,用0 – 9 、A – F 十五个字符来值,逢十六进一。
各位权值为 16^I
十六进制表示数值方法如下:
例:$$(56D.3)_H=5 \times 16^2 6 \times 16^1 13 \times 16^0 3 \times 16^{-1}$$

进位计数制之间的转换

二 → 十

二进制数从低到高(即从右到左)计算,第0位权值为20次方,第1位权值为21次方,第2位权值为22次方,依次增加,最终结果十进制。

八 → 十

八进制数从低到高(即从右到左)计算,第0位权值为80次,第1位权值为81次,第2位权值为82次,依次增加,最终结果加值为十进制。

十六 → 十

16进制数从低到高(即从右到左)计算。第0位权值为160次,第1位权值为161次,第2位权值为162次。依次增加,最终结果加值为10进制。

十 → 二

除2取余法,即每次将整数部分除以2,余数为该位权上的数,而业务继续除以2,余数为上一位权上的数。这一步一直持续到业务为0,最后读数时,从最后一个余数到最前一个余数。

十 → 八
  • 方法1
    除8取余法,即每次将整数部分除以8,余数为该位权上的数,商继续除以8,余数为上一位权上的数。这一步一直持续到商为0,最后读数时,从最后一个余数到最前一个余数。
  • 方法2
    采用间接法,先将十进制转化为二进制,再将二进制转化为八进制。
十 → 十六
  • 方法1
    除16取余法外,即每次将整数部分除以16,余数为该位权上的数,而业务继续除以16,余数为上一位权上的数。这一步一直持续到业务为0,最后读数时,从最后一个余数到最前一个余数。
  • 方法2
    使用间接法,先将十进制转换成二进制,然后将二进制又转换成十六进制。
二 → 八

取三合一法,即从二进制小数点为分界点,从左(右)取一个,然后按权利加三个二进制,然后按顺序排列。小数点的位置保持不变,得到的数字是我们要求的八进制数。如果向左(向右)取三位,得到最高(最低)位,如果不能凑三位,可以在小数点最左(最右)加0,也就是整数最高(最低),凑三位。

八 → 二

取一分三法,即将一位八进制数分解为三位二进制数,用三位二进制按权相加将这位八进制数凑合,小数点位置依旧。

二 → 十六

取四合一法,即从二进制的小数点到分界点,从左到右取一个,然后按权利加四个二进制,然后按顺序排列。小数点的位置保持不变,得到的数字是我们要求的16个进制数。如果向左(向右)取四位后,取到最高(最低)位时候,如果无法凑足四位,可以在小数点最左边(最右边),即整数的最高位(最低位)添0,凑足四位。

十六 → 二

取一分四法,即将一位十六进制数分解为四位二进制数,用四位二进制按权相加,将这位十六进制数加起来,小数点位置依旧。

十六 <-> 八

利用二进制实现转换

常用的计算机编码

BCD码

BCD码(Binary-Coded Decimal),用4位二进制数来表示1位十进制数中的0~9这10个数字,是二进制的数字编码形式,用二进制编码的十进制代码。BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。

-w543

ASCII码 -美国标准信息交换代码

ASCII ((American Standard Code for Information Interchange): 基于拉丁字母的计算机编码系统主要用于显示现代英语和其他西欧语言。它是最常见的信息交换标准,相当于国际标准ISO/IEC 646。ASCII1967年首次以标准类型发表,1986年最后一次更新,到目前为止共定义了128个字符。

带符号数的表示

数的表示

数的常用表示法:原码、反码、补码

机器数和真值
  • 机器数
    一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1。
    比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。那么,这里的 00000011 和 10000011 就是机器数。
  • 真值
    因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。
    例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1
原码

原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

[+1]原 = 0000 0001
[-1]原 = 1000 0001

第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:

[1111 1111 , 0111 1111]

即:

[-127 , 127]
反码

反码的表示方法是:

  • 正数的反码是其本身
  • 负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
补码

补码的表示方法是:

  • 正数的补码就是其本身
  • 负数的补码是在其原码的基础上, 符号位不变, 其余各位取反,
    最后+1. (即在反码的基础上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补

为什么使用原码反码补码

已知:计算机可以有三种编码方式表示一个数. 对于正数因为三种编码方式的结果都相同:

[+1] = [00000001]原 = [00000001]反 = [00000001]补

对于复数:

[-1] = [10000001]原 = [11111110]反 = [11111111]补

可见原码, 反码和补码完全不同。
对于计算机, 加减乘除是最基础的运算, 要设计的尽量简单。于是人将符号位也参与运算。 根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了。
计算十进制的表达式: 1-1=0
首先看原码:

1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2

如果用原码表示, 让符号位也参与计算, 显然对于减法来说, 结果是不正确的.这也就是为何计算机内部不使用原码表示一个数.
为了解决原码做减法的问题, 出现了反码:

1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0

发现用反码计算减法, 结果的真值部分是正确的. 而唯一的问题其实就出现在"0"这个特殊的数值上. 虽然人们理解上+0和-0是一样的, 但是0带符号是没有任何意义的. 而且会有[0000 0000]原和[1000 0000]原两个编码表示0.
于是使用补码, 解决了0的符号以及两个编码的问题:

1-1 = 1 + (-1) = [0000 0001]原+[1000 0001]原=[0000 0001]补+[1111 1111]补=[0000 0000]补=[0000 0000]原

这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128:

(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]补 + [1000 0001]补 = [1000 0000]补

(-1-127)的结果应该是-128, 在用补码运算的结果中, [1000 0000]补 就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000]原, 这是不正确的)
使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].
因为机器使用补码, 所以对于编程中常用到的32位int类型, 可以表示范围是: [-231, 231-1] 因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.

微机的一般概念

计算机的基本组成和工作原理

计算机的基本组成:运算器、控制器、存储器、以及输入和输出设备

微处理器(CPU)

CPU是大规模集成电路技术做成的芯片,芯片内集成有控制器、运算器和寄存器等相关部件,完成对计算机系统内各部件进行统一协调和控制。
包括:寄存器阵列(RS)算术和逻辑运算单元(ALU)控制器内部总线及缓冲器

  • 控制器:根据程序中的命令发出各种控制信号,使各部分协调工作以完成指令所要求的各种操作。
  • 运算器:对信息进行加工、运算的部件,执行算术运算和逻辑运算。
存储器

功能:存放程序和数据。
存储器=内存+外存。


内存是半导体存储器,外存通常是指光盘,硬盘等可长期保存信息。
半导体存储器包含RAM和ROM。
  • RAM:随机读写存储器(random access memory)。
    RAM主要用来存放各种数据,中间结果以及外存交换信息和作
    为堆栈。程序运行的时候通常从外存读入内存ram中,然后再
    由cpu从ram中读取并运行。
    • Sram静态存储器,cache。
    • Dram动态存储器用于主存。SDRAM:Synchronous
    • Dynamic Random Access Memory,同步动态随机存储器。
  • Rom:只读存储器(read only memory)。
  • Flash memory:闪速存储器,又叫闪存,是一种特殊的rom。
    每一个存储单元有一个确定的地址

    注意: 存储单元的地址和该地址单元中存放的内容是两个不同的概念。

I/O设备和I/O接口

I/O设备:微机配备的输入/输出设备(外设)。

存储程序工作原理

把编制好的程序和数据一起先送入存储器中保存起来。启动机器运行后,根据给出的程序中第一条指令的存储地址,控制器就可以根据存储程序中的程序周而复始的取出指令、分析指令、执行指令,直至完成全部指令操作,即控制器通过指令流的串行驱动实现程序控制。

名词术语

  • 微处理器:是将运算器和控制器做在一块集成电路上的一个独立部件。它具有解释指令、执行指令和与外界交换数据的能力。
  • 微机:通过总线把I/O、CPU和半导体存储器有机结合在一起。
    微机分为:单板机(印制电路板)、单片机(芯片)、多板机。
  • 微机系统:微机配上外部设备、系统电源和系统软件就构成微机系统。
  • 微机多机系统:多台微机/微处理器组合而成。
  • 微机开发系统(MDS):在研制开发微机应用系统时,从程序调试到样机的系统调试,他都能提供软件和硬件的支持
  • 计算机网络系统:借助通信网络将一定的域内的众多计算机和外设连接起来构成计算机网络可以实现计算机之间的互相通信和资源共享。
  • 多媒体:文、图、声、像等单媒体与计算机程序融合在一起形成的信息传播媒体。

微机结构-微机的结构是一种总线结构

总线(Bus)是计算机各种功能部件之间传送信息的公共通信干线,它是由导线组成的传输线束, 按照计算机所传输的信息种类,计算机的总线可以划分为数据总线、地址总线和控制总线,分别用来传输数据、数据地址和控制信号。

  • 计算机的各个部件挂在总线上,总线使得计算机功能部件之间的相互关系变成各个功能部件面向总线的单一关系。
  • 优点:
    • 结构简单
    • 扩展维护方便

系统总线

从处理器引出的若干信号线,CPU通过它们与存储器或I/O设备进行信息交换。一个部件只要满足总线标准,就可以连接到采用这种总线标准的系统中。
系统总线分为:

  • 地址总线
  • 控制总线
  • 数据总线

地址总线

传递地址信息的总线,即AB。CPU在地址总线上输出将要访问的内存单元或I/O端口的地址,该总线为单向总线。

内存容量的计算:
  • 16条地址线可访问$2^{16} = 65536B = 64 KB$
  • 20条地址线可访问$2^{20} = 1 MB$
  • 1K = 1024B 1M = 1024 KB 1G = 1024 MB

控制总线

传递控制信息的总线,即CB。
一部分是从CPU输出:通过对指令的译码,由CPU内部产生,由CPU送到存储器、输入/输出接口电路和其它部件。如读写控制信号等。
另一部分是由系统中的其他外设产生,送往CPU,如:中断请求信号、总线请求信号、状态信号。

数据总线

传递数据信息的总线,即DB。
在CPU进行读操作时,内存或外设的数据通过数据总线送往CPU;
在CPU进行写操作时,CPU数据通过数据总线送往内存或外设,数据总线是双向总线。

微机的工作过程

准备

  • 1、编写程序(源程序);
  • 2、将源程序汇编或编译成计算机能识别的机器语言程序;
  • 3、将数据和程序放入存储器中存放。

取指令阶段的执行过程:(设程序从00H开始存放)

  • 1、将程序计数器(PC或IP)的内容送地址寄存器AR。
  • 2、程序计数器PC的内容自动加1变为01H,为取下一条指令作好准备。
  • 3、地址寄存器AR将00H通过地址总线送至存储器地址译码器译码,选中00H单元。
  • 4、CPU发出“读”命令。
  • 5、所选中的00单元的内容B0H读至数据总线DB上。
  • 6、经数据总线DB,读出的B0H送至数据寄存器DR。
  • 7、数据寄存器DR将其内容送至指令寄存器IR中,经过译码CPU“识别”出这个操作码为“MOV A,05H”指令,于是控制器发出执行这条指令的各种控制命令。

执行指令阶段的执行过程:

  • 1、将程序计数器(PC或IP)的内容送地址寄存器AR。
  • 2、程序计数器PC的内容自动加1变为02H,为取下一条指令作好准备。
  • 3、地址寄存器AR将01H通过地址总线送至存储器地址译码器译码,选中01H单元。
  • 4、CPU发出“读”命令。
  • 5、所选中的01H单元的内容05H读至数据总线DB上。
  • 6、经数据总线DB,读出的05H送至数据寄存器DR。
  • 7、由控制码计算机已知到读出的是立即数,并要求将它送入累加

计算机软件系统

系统软件和应用软件系统软件包括操作系统、各种高级语言处理程序、编译系统和其他服务程序、数据库管理系统等软件。这些软件不是用来解决具体应用问题的,而是利用计算机自身的功能,合理的组织解题流程,管理计算机软、硬件各种资源,提供人-机间的接口,从而简化或代替各环节中人所承担的工作。还可以为用户使用机器提供方便,扩大机器功能,提高工作效率。应用软件是由用户利用计算机及其系统软件编制的解决实际应用问题的程序。

Intel微处理器结构

8086的功能结构/编程结构

Intel 8086 微处理器有16位寄存器和16位外部数据总线,20位地址总线,寻址为1MB的地址空间。Intel 8088 微处理器的外部数据总线为8位,其他与8086是一样的。


8086 CPU从功能上划分成两部分:总线接口单元 BIU(Bus Interface Unit)和执行单元 EU(Execution Unit).
BIU根据EU的请求,将指令送到指令流队列中排队,为EU提供即将执行的指令;EU从BIU的指令队列取得的指令和数据,来对片外操作数(片外就是指CPU以外存储数据的地方,比如存储器,IO接口等)进行访问的。这样EU与BIU可独立工作,BIU在保证EU与片外传输操作数的前提下,可进行指令预取,与EU可重叠操作。取指部分与执行部分可分开进行,提高CPU的利用率。(8086指令队列出现2个空字节,且EU未占总线,BIU自动取指令填充队列。)
  • BIU作为总线控制单元,负责与存储器及IO接口来传输数据。
    • BIU的组成部分:段寄存器组(CS,DS,SS,ES)、指令指针(IP)、地址加法器、指令队列缓冲器、总线接口控制逻辑。
  • EU作为执行单元,负责执行指令。
    • EU的组成部分:16位通用寄存器组(AX,BX,CX,DX,SP,BP,SI,DI)、算术逻辑单元(ALU)、标志寄存器(FLAG)、操作控制器电路。

BIU

1.段寄存器组(CS,DS,SS,ES)
  • CS:代码段寄存器,存放当前将被执行的程序的段地址。
  • DS:数据段寄存器,存放当前被执行的程序所用操作数的段地址。
  • SS:堆栈段寄存器,存放当前被执行的程序所用堆栈的段地址。
  • ES:附加段寄存器,存放当前被执行程序所用操作数的段地址。
  • 其中,DS、SS和ES寄存器的内容可由程序设置,而CS寄存器的内容不能用程序设置。
2.指令指针寄存器(IP)

它主要用来存放将要执行的下一条指令的偏移量,与CS联合形成下一条指令的物理地址。

3.地址加法器

它用来计算物理地址的,物理地址的形成:
理地址 = 段基地址×10H + 偏移量
8086微处理器有20条地址总线,可寻址1MB的存储器空间。由于8086微处理器是一个16位结构,段寄存器均为16位,这样16位寄存器就无法存放20位地址了。为了解决这个问题,8086内部就设置了一个20位的地址加法器,它首先将16位的段地址左移4位,然后再与16位的偏移地址相加形成20位的物理地址,如图:


每当取指令的时,则自动选择代码段寄存器CS,再加上由指令指针寄存器(IP)提供的16位偏移量,按上述方法计算后得到所要取的指令的20位物理地址。
4.指令队列缓冲器

它是一个6B的先进先出缓冲器。8086微处理器具有指令预取功能,当执行部件(EU)不使用总线接口部件与片外进行数据传送,总线接口部件就可以从存储器中读取指令填充指令队列缓冲器。 8088微处理器的指令队列缓冲器只有4B深度。

5.总线接口控制逻辑

这部分电路是处理器与外部总线的接口,它首先把已形成的20位地址码经地址线送出片外,然后经数据总线进行操作数或指令代码的传输。操作数送相关寄存器或由相关寄存器送到片外,而指令代码从片外存储器读入到指令队列等待译码执行。

EU

1.16位通用寄存器组(AX,BX,CX,DX,SP,BP,SI,DI)
(1)4个16位通用的数据寄存器:AX、BX、CX、DX,又可以各分为两个8位的寄存器:AL、AH、BL、BH、CL、CH、DL、DH

其中:
AX: 具有累加功能,可作16位累加器,AL可作为8位累加器。
BX: 在基址变址寻址时作为基址寄存器。
CX: 在循环类与串处理类指令执行时作为默认的计数器寄存器。
DX: 作为数据寄存器使用,在双字运算中存放高16位数据。

(2)另外四个地址指针和变址寄存器

SP(Stack Pointer):堆栈指针寄存器,用来指出堆栈的顶部偏移地址。
BP(Base Pointer):基地址指针寄存器,在间接寻址时作为基地址寄存器。
SI(Source Index):源变址寄存器,在间接寻址时作为地址寄存器或变址寄存器。在字符串处理指令中,作为目的变址寄存器。
DI(Destination Index):目的变址寄存器,在间接寻址时作为地址寄存器或变址寄存器。在字符串处理指令中,作为源变址寄存器。

2.算术逻辑单元(ALU)

它主要完成算术运算、逻辑运算。

3.标志寄存器(FLAG)

它是一个16位的寄存器,用来记录程序中运行结果的状态信息,它们是根据有关指令的运行结果由 CPU 自动设置的。其中9位有定义, 9位中6位表示状态,3位表示控制标志,见图


(1)进位标志(CF):运算指令执行之后,若在最高位上产生进位、借位时,该标志位被置1。 具体地说,两个数相加时,最高位(D15或D7)有进位,或当两个数相减时,最高位有借位,进位标志位被置1,即CF=1;否则CF=0。
(2)奇偶标志(PF):8086/8088 CPU中采用奇校验,运算指令执行后,运算结果的低8位中含1的位数为偶数时,该标志位被置1,否则被置0。也称为偶标志位。
(3)辅助进位标志(AF):运算指令执行后。当两个数相加(减)时,当D3有向D4进(借)位时,该标志位被置1,否则被置0。
(4) 全零标志(ZF):运算指令执行后,结果的每一位都为零时该标志位被置1。
(5) 符号标志(SF):在带符号数运算时,如果运算结果最高位为1,表示结果为负值,SF位被置1,否则SF位被置0。SF也称为负标志位。
(6)溢出标志(OF):运算指令执行后,结果的数值产生溢出,该标志位被置1,否则被置0。
(7)方向标志(DF):用于字符串指令操作,当DF=0时,字符串处理由低地址向高地址处理;当DF=1时,则从高位地址向低位地址处理。
(8)中断允许标志(IF):用来控制可屏蔽硬件中断。当IF=1时8086微处理器可以接受片外来的可屏蔽中断请求,开中断;IF=0时片外来的中断请求被阻止,关中断,也称被屏蔽。
(9)陷阱标志(TF):该标志用来控制单步中断。在TF=1时,以单步方式执行程序。即8086每执行完—条指令就产生处理器内部单步中断。单步执行指令可使程序员跟踪指令的执行过程,进行积序的调试。
4.操作控制电路

操作控制电路是8086微处理器的控制核心,首先将指令队列中送来的一条指令进行译码,然后根据不同指令的功能产生出所需要的控制信号来控制各相关功能部件的操作。

8086、8088的功能结构

微处理器 8086, 8088结构类似。从程序员和使用角度来看的结构即编程结构从功能上分为两部分:总线接口部分BIU(Bus Interface Unit),执行部分EU(Execution Unit)。
由于指令队列的存在,两部分各自执行自己的功能并行工作,这种工作方式与传统的计算机在执行指令时的串行工作相比极大的提高了工作效率。
计算机执行程序时,CPU的工作顺序是:

  • 取指令 -> 执行指令 -> 再取指令 -> 再执行指令...CPU串行工作。
  • 8086CPU工作顺序是:取指令,执行指令同时进行。并行工作。

8088的寄存器结构

存储器组织

8088的功能结构

  • 1、总的存储空间为1M字节,每段最长可达 64K字节。
  • 2、各段起始地址能被 16 整除。(低 4 位为 0 )
  • 3、各段之间可分开、部分或完全重叠、可首尾相接。
  • 4、根据各段的用途将其定义为CS、DS、ES、SS段。并用偏移地址(距段起址的字节距离)表示被访问单元。

注:常在CS中用 IP 表示偏移量,SS中用 SP、BP,DS中用 BX、SI、DI、数值 。

实际地址的形成

  • 物理地址:20 位
  • 逻辑地址:
    段基址(段寄存器的内容)16位
    偏移地址(字节距离)16位
    一个实际地址可用多个逻辑地址表示。

标志寄存器

  • CF:进位标志位。当执行一个加法(或减法)运算使最高位产生进位(或借位)时,CF为1,否则为0。
  • PF:奇偶标志位。该标志位反映运算结果中1的个数是偶数个还是奇数个。当指令执行结果的低8位中含偶数个1时,PF为1,否则为0.
  • AF:辅助进位标志位。当执行一个加法(或减法)运算使结果的低4位向高4位有进位(或借位)时,AF为1,否则为0.
  • ZF:零标志位。若当前的运算结果为零,ZF为1,否则为0.
  • SF:符号标志位。他与运算结果的最高位相同。
  • OF:溢出标志位。当补码运算有溢出时,OF为1,否则为0.
  • DF:方向标志位。用以指定字符串处理的方向,当DF=1,字符串以递减顺序处理,即地址以从高到低顺序递减。反之则以递增处理。
  • IF:中断允许标志位。它用来控制8086是否允许接收外部中断请求。若IF=1,8086能响应外部中断。反之则不响应。注意:IF的状态不影响非屏蔽中断请求(NMI)和CPU内部中断请求。
  • TF:跟踪标志位。为调试程序而设定的陷阱控制位。当TF=1,8086CPU处于单步状态,此时CPU每执行完一条指令就自动产生一次内部中断。当该复位后,CPU恢复正常

8086指令系统

数据传送指令:MOVXCHGLEALDSLESPUSHPOPPUSHFPOPFCBWCWDCWDE

算术指令:ADDADCINCSUBSBBDECCMPMULDIVDAADASAAAAAS

逻辑指令:ANDORXORNOTTESTSHLSALSHRSARRCLRCRROLROR

控制转移指令:JMPJccJCXZLOOPLOOPZLOOPNZLOOPNECALLRETINT

串操作指令:MOVSLODSSTOSCMPSSCAS

标志处理指令:CLCSTCCLDSTD

数据传送指令

通用数据传送指令

MOV dst, src;传送指令(move)

执行操作:(dst) ← (src)
功能: 将源操作数(字节或字)传送到目的地址。

注意:

  • 目的操作数dst和源操作数src不能同时用存储器寻址方式,这个限制适用于所有指令;
  • 目的操作数dst不能是CS,也不能用立即数方式;
  • 目的操作数dst和源操作数src不允许同时为段寄存器;
  • MOV指令不影响标志位。
PUSH   src ; 进栈指令(push onto the stack)

执行操作: (SP) ← (SP)-2
      ((SP)) ← (src)

POP    dst ; 出栈指令(pop from the stack)

执行操作: (dst) ← ((SP))
      (SP) ← (SP)+2

PUSH和POP指令分别将数据存入堆栈或把堆栈中的数据取出。堆栈是以LIFO(后进先出)方式工作的一个存储区,程序中定义的堆栈段就是这样一个LIFO存储区。数据存入堆栈单元或从堆栈单元中取出都由堆栈指针SP指示,而SP总是指向栈顶,所以进栈和出栈指令都会自动修改SP。

PUSH指令执行时,SP的内容先减2,然后将数据压入SP所指示的字单元,存储的方法同样是高8位存入高地址字节,低8位存入低地址字节。POP指令执行时,将SP所指示的栈顶地址的内容取出放入目的地址,然后SP增2,指向新的栈顶地址。

注意:

  • PUSH和POP指令只能是字操作,因此存取字数据后,SP的修改必须是+2或-2;

  • PUSH和POP指令不能使用立即数方式;

  • POP指令的dst不允许是CS寄存器;

  • PUSH和POP指令都不影响标志位。

    PUSH指令在程序中常用来暂存某些数据,而POP指令又可将这些数据恢复。

XCHG  opr1, opr2 ; 交换指令(exchange)

执行操作:(opr1) ←→ (opr2)
XCHG指令使两个操作数opr1,和opr2互相交换,其中一个操作数必须在寄存器中,另一个操作数可以在寄存器或存储器中。

注意:

  • 不允许使用段寄存器
  • 不影响标志位

累加器专用传送指令

这组指令只限于使用累加器(ac:AX 或AL)传送信息。

IN  ac, port ; 输入指令(input), port≤0FFH

执行操作: (AL) ← (port) 传送字节或 (AX) ← (port+1,port) 传送字

IN  ac, DX  ; 输入指令, DX中的port>0FFH

执行操作: (AL) ← ((DX)) 传送字节或 (AX) ← ((DX)+1,(DX)) 传送字

OUT  port, ac  ; 输出指令(output), port≤0FFH

执行操作: (port) ← (AL) 传送字节或 (port+1,port) ← (AX) 传送字

OUT  DX, ac   ; 输出指令(output), DX中的 port>0FFH

执行操作: ((DX)) ← (AL) 传送字节或 ((DX)+1,(DX)) ← (AX) 传送字

对8086及其后继机型的微处理机,所有I/O端口与CPU之间的通信都由输入输出指令IN和OUT来完成。IN指令将信息从I/O输入到CPU,OUT指令将信息从CPU输出到I/O端口,因此,IN和OUT指令都要指出I/O端口地址。微处理机分配给外部设备最多有64K个端口,其中前256个端口(0~FFH)称为固定端口,可以直接在指令中指定。当端口地址超过8位(≥256),称为可变端口,它必须先送到DX寄存器,然后再用IN或OUT指令传送信息。CPU与I/O端口传送信息的寄存器只限于累加器ac (AX或AL),传送16位信息用AX,传送8位信息用AL,这取决于外设端口的宽度。

注意:

  • 只限于在AL或AX与I/O端口之间传送信息
  • 不影响标志位
XLAT   ; 换码指令(translate)

执行操作: (AL) ← ((DS)×16+(BX)+(AL))
这条指令根据AL寄存器提供的位移量,将BX指示的字节表格中的代码换存在AL中。该指令还可写为:XLAT opr,opr为字节表格的首地址,因为opr所表示的偏移地址已存入BX寄存器,所以opr在换码指令中可有可无,有则可提高程序的可读性。

注意:

  • 所建字节表格的长度不能超过256字节,因为存放位移量的是8位寄存器AL;
  • XLAT指令不影响标志位。

地址传送指令

这组指令完成把地址送到指定寄存器的功能。

LEA reg, src ; 有效地址送寄存器(load effective address)

执行操作:(reg) ← offset of src
LEA指令把源操作数的有效地址送到指定的寄存器,这个有效地址是由src选定的一种存储器寻址方式确定的。

LDS reg, src ; 指针送寄存器和DS(load DS with point)

执行操作: (reg) ← (src)(DS) ← (src+2)

LES reg, src ; 指针送寄存器和ES(load ES with point)

执行操作: (reg) ← (src)(ES) ← (src+2)

LDS和LES指令把确定内存单元位置的偏移地址送寄存器,段地址送DS或ES。这个偏移地址和段地址(也称地址指针)是由src指定的两个相继字单元提供的。

注意:

  • 指令中的reg不能是段寄存器;
  • 指令中的src必须使用存储器寻址方式;
  • 该指令不影响标志位。

标志寄存器传送指令

这组指令完成和标志位有关的操作。

LAHF 标志寄存器的低字节送AH(load AH with flags) 
SAHF AH送标志寄存器低字节(store AH into flags)
PUSHF 标志进栈(push the flags)
POPF 标志出栈(pop the flags)

注意:

  • LAHF和SAHF指令隐含的操作寄存器是AH和FLAGS
  • LAHF和PUSH不影响标志位,SAHF和POPF则由装入的值来确定标志位的值。

LAHF 标志寄存器的低字节送AH(load AH with flags)执行操作:(AH) ← (FLAGS)0-7

SAHF AH送标志寄存器低字节(store AH into flags)执行操作:(FLAGS) 0-7 ← (AH)

PUSHF 标志进栈(push the flags)执行操作:(SP) ← (SP)-2((SP)+1,(SP)) ← (FLAGS)0-15

POPF 标志出栈(pop the flags)执行操作:(FLAGS) 0-15 ← ((SP)+1,(SP))(SP) ← (SP)+2

算术指令

加法指令

ADD 加法指令

写法: ADD DST,SRC
执行操作:(DST)<-(SRC)+(DST)

ADC 带进位加法指令

写法: ADC DST,SRC
执行操作:(DST)<-(SRC)+(DST)+CF

ADD 加1指令

写法: INC OPR
执行操作:(OPR)<-(OPR)+1

减法指令

SUB 减法指令

写法: SUB DST,SRC
执行操作:(DST)<-(DST)-(SRC)

SBB 带借位减法指令

写法: SBB DST,SRC
执行操作:(DST)<-(DST)-(SRC)-CF

DEC 减1指令

写法: DEC OPR
执行操作:(OPR)<-(OPR)-1

NEG 求补指令

写法: NEG OPR
执行操作:(OPR)<- -(OPR)

CMP 比较指令

格式: CMP OPR1,OPR2
执行操作:(OPR1)-(OPR2)

逻辑指令

AND\OR\XOR\NOT\TEST

写法:

AND reg/mem,reg/mem/imm;
OR reg/mem,reg/mem/imm;
XOR reg/mem,reg/mem/imm;
NOT reg/mem;
TEST reg/mem,reg/mem/imm;

AND\TEST\OR\XOR,两个操作数必须类型匹配,而且不能同时是内存操作数。

XOR通常用来将寄存器清0,如 XOR AX,AX;

TEST与AND的关系类似于CMP与SUB。TEST的典型用法是检查某位是否为1

位移指令

SHL(逻辑左移)

写法:SHL REG\mem,1\CL ;

作用:将dest的各个二进制位向左移动1(CL)位,并将DEST的最高位移出到CF,最低位移入0。

SAL(算术左移)

写法:SAL REG\mem,1\CL ;

作用:将dest的各个二进制位向左移动1(CL)位,并将DEST的最高位移出到CF,最低位移入0(同SHL)。

SHR(逻辑右移)

写法:SHR REG\mem,1\CL ;

作用:将dest的各个二进制位向左移动1(CL)位,并将DEST的最低位移出到CF,最高位移入0。

SAR(算术右移)

写法:SAR REG\mem,1\CL ;

作用:将dest的各个二进制位向左移动1(CL)位,并将DEST的最低位移出到CF,最高位不变。

SHLD(双精度左移)

写法:SHLD REG16/REG32/MEM16/MEM32, REG16/REG32, IMM8/CL;(类型须匹配)

作用:将OPRD1的各二进制左移,并将oprd1的最高位移到CF,oprd2的最高位移到oprd1的最低位,但是,oprd2的值不变。

SHRD(双精度右移)

写法与作用与双精度左移类似。移动方向为右移。

循环移位指令

ROL(循环左移)

写法:ROL REG\MEM, 1\CL;或 ROL REG/MEM,IMM8;(类型可不匹配)

作用:将DEST的各二进制位向左移动,并将最高位移出到CF,并同时移入最低位。

ROR(循环右移)

写法:ROR REG\MEM, 1\CL;或 ROR REG/MEM,IMM8;(类型可不匹配)

作用:将DEST的各二进制位向右移动,并将最低位移出到CF,并同时移入最高位。

RCL(带进位循环左移)

写法:RCL REG\MEM, 1\CL;或 RCL REG/MEM,IMM8;(类型可不匹配)

作用:将DEST的各二进制位向左移动,并将最高位移出到CF,原CF移入最低位。

RCR(带进位循环右移)

写法:RCR REG\MEM, 1\CL;或 RCR REG/MEM,IMM8;(类型可不匹配)

作用:将DEST的各二进制位向右移动,并将最低位移出到CF,原CF移入最高位。

位测试指令

BT(位测试)

写法:BT REG16/MEM16,REG16/IMM8;或BT REG32/MEM32,REG32/IMM8;

作用:CF=DEST的第index位,dest不变。

BTS(位测试并置位)

写法:BTS REG16/MEM16,REG16/IMM8;或BTS REG32/MEM32,REG32/IMM8;

作用:CF=DEST的第index位,dest的第index位=1;

BTR(位测试并复位)

写法:BTR REG16/MEM16,REG16/IMM8;或BTR REG32/MEM32,REG32/IMM8;

作用:CF=DEST的第index位,dest的第index位=0;

BTC(位测试并复位)

写法:BTC REG16/MEM16,REG16/IMM8;或BTC REG32/MEM32,REG32/IMM8;

作用:CF=DEST的第index位,dest的第index位取反;

位扫描指令

BSF(前向位扫描)

写法:BSF reg16/reg32, reg16/reg32/mem16/mem32;(类型须匹配)

作用:dest=src中值为1的最低位编号(从低位向高位搜索)

BSR(后向位扫描)

写法:BSR reg16/reg32, reg16/reg32/mem16/mem32;(类型须匹配)

作用:dest=src中值为1的最高位编号(从高位向低位搜索)

说明:BSF和BSR搜索SRC操作数中首次出现1的位置,BSF从低位向高位搜索,BSR反之。若找到一个1,则置ZF=0,并存储位编号到DEST操作数中。若SRC=0,即没有1出现,则置ZF=1,且dest的值不确定。

控制转移指令开始

JMP(无条件转移指令)

执行代码的跳转,分为两种,一:段内转移,即要跳过去的代码地址和当前地址在同一段,这时只要修改IP(专用寄存器–指令指针)即可;二:段间转移:即要跳过去的代码地址和当前代码地址不在同一段内,需要同时修改CS和IP的值。

写法:

1、JMP label;若label与该指令位于同一代码段内,IP=label的偏移地址,否则CS:IP=label的分段地址,简单的说,就是跳到label的地址去。

2、JMP reg16/mem16;段内转移,偏移地址=reg16/[mem16]

3、JMP mem32;段间间接转移,段地址CS=mem32高字,偏移地址IP=mem32低字。

说明:当操作数是内存操作数时,若内存操作数是双字类型,则产生段间转移,若内存操作数是字类型,则产生段内间接转移。当不能确定类型时,编译器将报错。

Jcc(条件转移指令)

写法:Jcc label;

作用:若条件成立,则IP=label的偏移地址,否则,CPU将忽略该条件转移,继续执行下一条指令。

JCXZ/JECXZ(Jump if CX/ECX is zero)

写法:JCXZ label;(若CX=0,则转移到label)

​ JECXZ label;(若ECX=0,则转移到label)

说明:label相对位移量必须在-126~127之间

循环指令

LOOP label;

作用:CX=CX-1;若CX<>0,则转移到label;

LOOPZ/LOOPE label;

作用:CX=CX-1;若CX<>0且 ZF=1,则转移到label;

LOOPNZ/LOOPNE label;

作用:CX=CX-1;若CX<>0且ZF=0,则转移到label;

说明:label相对位移量必须在-128~127之间

过程调用和返回指令

CALL(过程调用)

写法:CALL label;

作用:若label与该指令在同一代码段,则为段内直接调用,IP进栈,IP=label的偏移地址,如果是不在同一代码段,则为段间间接调用,CS:IP进栈,CS:IP=label的分段地址

写法:CALL reg16/mem16;

作用:段内间接调用,IP进栈,IP=reg16/【mem16】

写法:CALL mem32;

作用:段间间接调用,CS:IP进栈,CS等于mem32高字,ip等于mem32低字。

该指令与JMP指令的区别就是保存了CS:IP的值,这样在调用指令结束后,可以返回回来而已。

RET(过程返回)

写法:RET; 近返回或远返回

RETN; 近返回;

RETF; 远返回

RET imm16; 近返回或远返回,并调整堆栈,SP=SP+imm16;

RETN imm16;近返回,并调整堆栈,SP=SP+imm16;

RETF imm16;远返回,并调整堆栈,SP=SP+imm16;

作用:RET/RETN/RETF:返回地址出栈,从而使调用返回,其中,远返回是POP一个双字到CS:IP,而近返回是POP一个字到IP

RET/RETN/RETF imm16:在返回后,CPU立即将imm16加到堆栈指针SP。这种机制用来在返回前将参数从栈中移除。

说明:CALL 与 RET必须配合使用,并且确保返回时栈顶正好是返回地址,不然就会出错。

INT(中断指令)

写法:INT n;(n为中断号,取值为0~255)

通常,程序内部的跳转,用JMP或CALL,并且JMP和CALL得参数是要跳转的过程的入口指令地址,而INT则是调用系统提供的中断服务程序,并且参数是中断号,然后由CPU根据中断号去计算中断服务程序的入口地址,MS DOS使用中断号21H作为系统调用,一般INT中断的步骤如下:

(1)由AH给出中断号

(2)根据相应功能的要求,设置入口参数

(3)INT 21H

(4)分析和使用出口参数

除了直接以AL或AX返回出口参数外,INT 21H还是用AL或AX作为返回码,对于功能号0~2eh,由AL返回0(表示成功)或1(表示失败);其余功能号则由CF返回0或者1,并由AX返回错误码。

标志处理指令开始

CLC ; CF=0

STC ; CF=1

CMC ; CF=NOT CF

CLD ; DF=0

STD ; DF=1

CLI ; IF=0(应慎用)

STI ; IF=1

串操作指令开始

MOVS(串传送)

写法:

MOVSB/MOVSW/MOVSD

功能:

ES:[DI]=DS:[SI]

If(DF=0)

Then

SI=SI+size;

DI=DI+size;

Else

SI=SI-size;

DI=DI-size;

Endif

其中,size等于1(B)、2(W)、4(D).

作用:将DS:SI所指源串的一个字节/字/双字复制到ES:DI所指的内存单元,然后,若DF=0,则SI和DI增加1、2、4,否则减少1、2、4.

LODS(串载入)

写法:LODSB\LODSW\LODSD

功能:

AL/AX/EAX=DS:[SI];

IF (DF=0) THEN

SI=SI+size;

ELSE

SI=SI-size;

Endif

作用:将DS:SI所指源串的值复制到AL/AX/EAX中,然后,根据DF使SI增加或减小1、2、4

STOS(串存储)

写法:

STOSB\STOSW\STOSD

功能:

ES:[DI]=AL/AX/EAX;

IF (DF=0) THEN

DI=DI+size;

ELSE

DI=DI-size;

ENDIF

作用:将AL/AX/EAX中的值复制到ES:[DI]所指的内存单元中去,并根据DF标志位的值调整DI

CMPS(串比较)

写法:CMPSB/CMPSW/CMPSD

功能:

DS:[SI]-ES:[DI];

IF (DF=0) THEN

SI=SI+size;DI=DI+size;

ELSE

SI=SI-size;DI=DI-size;

ENDIF

作用:将DS:SI所指内存值与ES:DI所指内存值进行比较,并根据比较结果设置标志位,然后,对SI和DI做相应的调整。

SCAS(串扫描)

写法:SCASB/SCASW/SCASD

功能:

AL/AX/EAX-ES:[DI];

IF (CF=0) THEN

DI=DI+size;

ELSE

DI=DI-size;

ENDIF

作用:将AL/AX/EAX与ES:DI所指内存值进行比较,根据比较结果设置标志位,然后根据DF调整相应的DI的值。

说明:以上串操作的共性:

DS:SI指向源串,ES:DI指向目的串

重复前缀

43、重复前缀

重复前缀用来和以上几个串操作指令混合使用

REP(重复)

功能:当CX<>0时,重复执行后面的串指令,每执行一次,CX自动-1,该指令只能用在MOVS\LODS\STOS之前

REPZ/REPE(为零/等于时重复)

功能:当CX<>0且ZF=1时,重复执行后面的指令,每执行一次,CX自动-1,该指令只能用在CMPS\ACAS之前。

REPNZ/REPNE(非零/不等于时重复)

功能:CX<>0且ZF=0时,重复执行后面的指令,每执行一次,CX自动-1,该指令只能用在CMPS\ACAS之前。

说明:REPNE SCAS(B/W/D)适用于在多字节、字、双字数据结构中搜索特定值。

CPU控制指令-

—————————CPU控制指令-

NOP(无操作)

写法:NOP;

作用:该指令不做任何事情,只占用1个字节,耗费一个指令执行周期。

HIT(暂停)

写法:HIT;

作用:HIT使CPU进入暂停状态,这时CPU不执行任何操作,直到系统复位或发生外部中断为止,中断使CPU继续执行后面的指令(貌似和屏保或待机的功能类似)

LOCK(封前缀)

功能:LOCK指令用于多处理器系统,作为某些指令的前缀,可以使CPU通过锁住总线等方式,抱着指令作为原子性操作,即:指令执行过程不会被打断操作。

该指令用于以下指令的前缀时,以保证原子性的对内存的“读-修改-写”操作:

1) 加法:ADD\ADC\INC\XADD

2) 减法:SUB\SBB\DEC\NEG

3) 交换:XCHG\CMPXCHG\CMPXCHG8B

4) 逻辑:AND\NOT\OR\XOR

5) 位测试:BTS\BTC\BTR

说明:其他类型指令不能加LOCK前缀,另外,XCHG总是原子性操作,无论前面有没有加LOCK前缀。LOCK前缀典型用于BTS指令,以实现多处理器环境中程序的并发执行,如:

LOCK BTS [EBX],AX

LOCK ADD [SI],AL