microcomputer_principle_04_指令系统和数据传输类指令
Carpe Tu Black Whistle

8086指令系统

8086的指令系统有96条指令。
但是在实际使用中,程序内的80%指令,存在于指令集的20%

从功能上包括六大类:

  • 数据传送
  • 算数运算
  • 逻辑运算和移位
  • 串操作
  • 程序控制
  • 处理控制

掌握要点

  • 指令码的含义
  • 指令对操作数的要求
  • 指令的对标志位的影响
  • 指令的功能

数据传送类指令

  1. 通用数据传送指令
  2. 输入输出指令
  3. 地址传送指令
  4. 标志传送指令

除标志传送指令外,其它指令的执行对标志位不产生影响。

通用数据传送

  • 一般数据传送指令
  • 堆栈操作指令
  • 交换指令
  • 查表转换指令
  • 字位扩展指令

该类所有指令的执行均不影响标志位

一般数据传送指令

  • 一般数据传送指令 MOV
  • format:
    • MOV dest, src
  • manipulation:
    • src –> dest
  • example:
    • MOV AL, BL

注意的点:

  • 两操作数字长必须相同
  • 两操作数不允许同时为存储器操作数
  • 两操作数不允许同时为段寄存器
  • 在源操作数是立即数时,目标操作数不能是段寄存器
  • IP和CS不作为目标操作数,FLAGS一般也不作为操作数在指令中出现

e.g.

第一段汇编语言

将(*)的ASCII码2AH写入内存数据段1000H开始的100个单元

题目分析:

  1. 确定首地址
  2. 确定数据长度
  3. 写一次数据
  4. 修改单元地址
  5. 修改长度值
  6. 判断是否写完
  7. 未完继续写入,否则结束

cycle

1
2
3
4
5
6
7
8
      MOV DI, 1000H
MOV CX, 64H
MOV AL, 2AH
AGAIN:MOV [DI], AL
INC DI ; DI+1, increase
DEC CX ; CX-1, decrease
JNZ AGAIN ; CX not equal to 0, continute; judge not equal zero
HLT

堆栈操作指令

  • 堆栈才做的原则
    • 先进后出
    • 以字为单位(16位计算机系统中,一个字的长度是16位,两个字节)
  • 堆栈操作指令:
    • 压栈指令
      • format PUSH OPRD(单操作数)
    • 出栈指令
      • format POP OPRD

压栈指令PUSH

  • 指令执行过程:
    • SP-2 –> SP
    • 操作数高字节–> SP+1
    • 操作数低字节–> SP

先提升栈顶,然后将高位字节放入SP+1位置

push

出栈指令POP

  • 指令执行过程:
    • SP –> 操作数低字节
    • SP+1 –> 操作数高字节
    • SP <– SP+2

先取出栈顶元素值,再进行压栈操作

堆栈操作指令说明

  • 指令的操作数必须为16位
  • 操作数可以是寄存器或存储器(两单元,)
  • 操作数不能是立即数
    • 单操作数格式的指令,对操作数有两点共同的要求
    1. 存储器操作数,必须声明字长
    2. 现式给出的单操作数,不能是立即数

push将一个数压入栈顶(src->SP(dest)
pop SP->dest
立即数是常数,没有地址含义。pop+立即数显然不行,push+立即数似乎可以,但是8086指令系统中,单操作数不能是立即数(硬规定)

交换指令

可以实现两个寄存器或者,寄存器与内存的互换

  • format:
    • XCHG REG, MEM/REG
  • requirement
    • 两操作数必须有一个是寄存器操作
    • 不允许使用段寄存器
  • e.g.
    • XCHG AX, BX
    • XCHG [2000], CL

查表指令

  • format
    *XLAT
    (隐含寻址)
  • explain:
    • BX的内容代表表格首地址
    • AL内容为表内位移量(8位)
    • BX+AL(表头地址+位移量)得到要查找元素的偏移地址
    • 最后取出DS:[BX+AL]的第一个字节–>AL
  • manipulation:
    • 将 BX+AL 所指单元的内容送AL

字位扩展指令

  • 将符号数的符号为扩展到高位;
  • 指令为零操作数指令,采用隐含寻址,隐含的操作数为AX及AX,DX
  • 无符号数的扩展规则为在高位补0

字节到字的扩展指令

  • format:
    • CBW
  • manipulation:
    • 将AL内容拓展到AX
  • rule:
    • 最高位=1,AH=FFH
    • 最高位=0,AH=00H

字到双字的扩展指令

  • format:
    • CWD
  • manipulation:
    • 将AX内容拓展到DX AX
  • rule:
    • 最高位=1,DX=FFFFH
    • 最低位=1,DX=0000H

输入输出指令

掌握:

  • 指令的格式及操作
  • 指令的两种寻址方式
  • 指令对操作数的要求

关于I/O端口

  • I/O端口:
    • I/O端口中用于存储数据、可以直接被CPU访问的寄存器。
  • 计算机输入输出系统中,可以包含若干接口控制电路(芯片),每个接口中都包含了1个或多个端口。

I/O port


  • 专门面向I/O端口操作的指令
  • 端口地址在指令中的表示方式——寻址方式
  • 指令功能:
    • 从端口地址读入数据到累加器/将累加器的值输出到端口中
  • format:
    • IN: IN acc, PORT
    • OUT: OUT PORT, acc

PORT是端口地址,acc=AL/AX acc绝对不会是AH

指令寻址方式

  • 根据 端口地址码 的长度,指令具有两种不同的端口地址表现形式。
  • 直接寻址
    • 端口地址为8位时,指令中直接给出8位端口地址;
    • 寻址256个端口。
  • 间接寻址
    • 端口地址为16位时,指令中的端口地址必须由DX指定;
    • 可寻址64K个端口。

地址传送指令

  • 取偏移地址指令LEA –> 取近地址指针
  • *LDS指令
  • *LES指令
    (以上两条指令 –> 取远地址指针

近地址和远地址的区别在于,是否储存逻辑段地址于DS或ES

LEA

  • manipulation:
    • 将变量的16位偏移地址写入到目标寄存器
  • 当程序中用符号表示内存偏移地址时,须使用该指令。
  • format:
    • LEA REG, MEM
  • requirement:
    • 源操作数必须时一个存储器操作数*,目标操作数通常是间址寄存器*。

      (将变量偏移地取出的目的,是为了方便修改指针)

diff MOV LEA

  • 将数据段中首地址为MEM1的50个字节的数据传送到同一逻辑段首地址为MEM2的区域存放。

image

1
2
3
4
5
6
7
8
9
10
      LEA SI, MEM1
LEA DI, MEM2
MOV CL, 50
NEXT: MOV AL, [SL]
MOV [DI], AL
INC SI
INC DI
DEC CL
JNZ NEXT ;条件转移
HLT

LDS,LES指令

  • LDS和LES均用于将一个32位的源地址指针写入到目标寄存器。
  • LDS(Load pointer using DS) format:
    • LDS 通用寄存器, 存储操作数
    • 将源操作数的偏移地址送目标寄存器
    • 将源操作数的段地址送DS
  • LES(Load pointer using ES) format:
    • LES 通用寄存器, 存储操作数
    • 将源操作数的偏移地址送目标寄存器
    • 将源操作数的段地址送ES

标志传送指令

  • LAHF (load AH from Flags)
  • SAHF (Store AH into Flag)
  • PUSHF (Push flags onto stack)
  • POPF (Pop flags off stack)

PUSHF和POPF两个标志传送指令,默认(隐含)操作数是FLAGS
LAHF和SAHF两个指令,隐含操作数AH

LAHF

  • format:
    • LAHF
  • manipulation: 将FLAGS的低8位装入AH

image

FLAGS寄存器中,只有低9位是有效的,因此,高7位是无效的。
这里两个指令,放弃了对第9位的操作,因为AH只有8位。

SAHF

  • format:
    • SAHF
  • manipulation: 将AH中的内容写入FLAGS的低8位中