跳转至

8086指令系统

  • 在学习过程中需要注意:
    • 寻址方式的多样性
    • 对标志寄存器的影响
    • 两个操作数类型匹配原则
      • 隐式匹配:两者之中有一个确定即可,CPU进行自动匹配
      • 显式匹配:两者大小都不确定,需要进行显式转换

数据传送指令

  • 特点:
    • 不变性:数据传送过程中不发生任何变化
    • 无其他副作用:对标志寄存器的内容物任何影响
    • 数据传送的Copy性质

传送指令MOV

mov dest, src
mov reg/mem/seg, reg/mem/seg/imm
- 将1字节或字的操作数从源地址src传送至目的地址dest - 源操作数:可以是立即数、寄存器或主存单元 - 目的操作数:可以是寄存器或主存单元 - 不能是立即数、IP、CS - 大小(类型/字与字节)要匹配 - 第二个操作数才是Src - 两个段寄存器之间不能直接传送数据 - 不允许两个操作数都是存储单元 - 立即数不能直接送入段寄存器mov ds, 100h - 想要传入一个立即数,需要先将这个数保存在数据寄存器中

交换指令XCHG

XCHG OPRD1, OPRD2
XCHG reg/mem, reg/mem
- 执行操作:将两个操作数的内容互换,可以在通用寄存器通用寄存器或存储器之间交换数据 - 注意: - 不允许使用段寄存器、IP - 不能同时为内存 - 交换的类型需要匹配

换码指令XLAT

XLAT
- 执行操作:\(AL\leftarrow DS:[(BX)+(AL)]\)所指的单元内容 - 使用该指令之前的预先工作: - 将表的首地址(偏移地址)\(\rightarrow\) BX - 将信息在表中的行号\(\rightarrow\)AL - 用途:查表 - 代码等价于:
mov ah, 0
add bx, ax
mov al, [BX]
- 使用例子:

堆栈操作指令

[!为什么需要堆栈] - 函数调用:断点和局部变量,参数的保存 - 临时存放数据,以便随时回复数据

进栈指令PUSH

PUSH src
PUSH reg16/seg/mem16
- 功能:先使堆栈指针\(SP-2\),然后把一个字操作数存入栈顶(\((SP)-2\rightarrow SP, (Src)\rightarrow SS:SP\)) - 注 - 必须是字 - 尽量不要使用PUSH SP

出栈指令POP

POP Dst
POP reg16/seg/mem16
- 功能:把栈顶的一个字传送至置顶的目的操作数,然后堆栈指针\(SP+2\)\((SS:SP)\rightarrow Dst, (SP)+2\rightarrow SP\)

标志寄存器传送指令

  • 标志寄存处传送指令用来传送标志寄存器的内容

标志寄存器传送指令

标志位操作

地址传送指令

有效地址传送指令LEA

LEA Dst, Src
LEA r16, mem
- 功能:\(Dst\leftarrow Src的偏移地址\) - 注:Dst为16位地址寄存器,Src为内存 - 这里的到的是主存单元中的有效地址,不是物理地址

指针传送指令

LDS Dst, Mem32
LES Dst, Mem32

LDS r16, mem
LES r16, mem
- 功能: - LDS:Mem32的低字\(\rightarrow\)Dst,高字\(\rightarrow\)DS - LES:Mem32的低字\(\rightarrow\)Dst,高字\(\rightarrow\)ES

算数运算指令

状态标志

  • 进位标志CF(Carrier Flag)
    • 体现二进制数据最高位的进位或借位
  • 溢出标志OF(Overflow Flag)
    • 表示有符号证书进行加减运算的结果是否超出范围
  • 零标志ZF(Zero Flag)
    • 表示运算结果是否为0
  • 符号标志SF(Sign Flag)
    • 反映运算结果是正数还是负数
  • 奇偶标志PF(Parity Flag)
    • 反映运算结果最低字节中\(1\)的个数是偶数还是奇数
  • 调整标志AF(Adjust Flag)
    • 反映加减运算时最低半字节有无进位或借位

加法指令

ADD

ADD dst, src
- 功能:\(Dst\leftarrow Dst+Src\)

ADC

ADC dst, src
- 功能:\(Dst \leftarrow Dst + Src + CF\) - 用途:用于多字节数相加,不单独使用

[!多字节数相加]

INC

INC OP
- 功能:\(OP\rightarrow OP +1\) - 注:INC不影响CF标志

减法指令

SUB

SUB Dst, Src
- 功能:\(Dst\leftarrow Dst-Src\)

SBB

SBB Dst, Src
- 功能:\(Dst\leftarrow Dst-Src-CF\) - 用途:多字节数相减,不单独使用

[!多字节数相减]

DEC

DEC OP
- 功能:\(OP\leftarrow OP -1\) - 注:不影响CF

NEG

NEG OP
- 功能:求补\(OP\leftarrow \bar{OP}+1\) - 说明: - 以\(0-OP\)判断标志位 - 仅当\(OP=0\)时,\(CF=0\)否则\(CF=1\) - 仅当\(OP=-128 /-32768\)时,\(OF=1\)否则\(OF=0\)

CMP

CMP Dst, Src
- 功能:\(Dst-Src\)结果的特征状态\(\rightarrow F\),不影响\(Dst\)\(Src\)

乘法指令

MUL

MUL Src
MUL reg8/mem8; AX = AL * src
MUL reg16/mem16; DX:AX = AX * src
- 对于8位操作数:AX = AL * src - 对于16位操作数:DX:AX = AX * src

IMUL

  • 与MUL功能完全相同,完成了两个带符号数的相乘

除法指令

DIV

DIV Src
DIV reg8/mem8; AX/SRC
DIV reg16/mem16; (DX:AX)/SRC
- 结果存放方式 - DIV reg8/mem8 - \(AL\leftarrow 商\) - \(AH \leftarrow 余数\) - DIV reg16/mem16 - \(AX\leftarrow商\) - \(DX\leftarrow 余数\)

IDIV

  • 功能与DIV完全相同,完成了两个带符号数的相除
  • 余数与被除数符号一致

    [!注] - SRC不能为立即数 - 除法溢出错误:商太大,若无符号数除法,当被除数高半部分\(\ge\)除数时,溢出错误,产生0号中断

  • 例子:同位数相除:

拓展指令

  • CBWCWD功能:将符号位进行拓展
    • CBW\(AL\rightarrow AX\)
    • CWD\(AX\rightarrow (DX,AX)\)

逻辑运算和移位指令

逻辑运算指令

AND

  • 执行操作:\(DST \leftarrow DST \wedge SRC\)
  • 用途:用于屏蔽一个数的某些位

OR

  • 执行操作:\(DST \leftarrow DST \vee SRC\)
  • 用途:用于置位一个数的某些位

XOR

  • 执行操作:\(DST\leftarrow DST \oplus SRC\)
  • 用途:将一个数的某些位取反

TEST

  • 执行操作:\(OPR1 \wedge OPR2\)
  • 用途:用于测试一个数的某些位,比较结果在ZF中

NOT

  • 执行操作:\(OPR \leftarrow \neg OPR\)
  • 用途:按位取反

    [!AND VS TEST] - AND具有破坏性,而TEST没有 - 同SUB和CMP

移位指令

  • 分类:
    • 逻辑:SHL/SHR
    • 算数:SAL/SAR
    • 循环:ROL/ROR
    • 带进位循环:RCL/RCR
  • 共同特点:
    • 都是按位进行
    • 当移动的位数为一位时,用立即数1
    • 当移动一位以上时,要预先将移动的位数存放在CL
      • SHL AL, 2\(\rightarrow\)MOV CL, 2; SHL AL, CL;
  • 32位数据的移动方式:

控制转移指令

无条件转移指令

  • 格式:JMP 地址表达式
  • 功能:使程序的流程无条件跳到转移地址所指的地方
    • 转移目的地址:CS*16+IP
    • 段内转移:改变IP的内容,CS的内容不变
    • 段间转移:IP、CS的内容都改变

段内直接转移(相对寻址)

  • 指令中直接给出到达的目标地址
  • 转移范围:\(-32768\sim 32767\)
    JMP PROG1;
    

段内间接转移(间接寻址)

  • 指定某个寄存器的内容或某个子单元的内容作为转移地址的偏移地址
  • 几个例子:
    • JMP BX\(BX\rightarrow IP\)
    • JMP WORD PTR[1000H]\(DS:1000H\rightarrow IP\)
    • JMP WORD PTR[SI+2]\(DS:SI+2\rightarrow IP\)
    • JMP TABLE[BX]\((DS:TABLE+BX)\rightarrow IP\)

段间直接转移(直接寻址)

  • 通过标号直接给出转移地址
  • JMP NEXTP1:NEXTP1的段址\(\rightarrow\)CS,偏址\(\rightarrow\)IP

段间间接转移(间接寻址)

  • 指定一个4字节的单元内容作为转移地址
    • 低二字节\(\rightarrow IP\)
    • 高二字节\(\rightarrow CS\)
  • JMP DWORD PTR[100H]

条件转移指令

标志位条件转移指令

[[8086指令系统#状态标志|状态标志]]

两个无符号数比较转移指令

两个有符号数比较转移指令

循环指令LOOP/LOOPE/LOOPNE

  • 格式:LOOP 标号
    • 功能:\(CX-1\rightarrow CX\),若\(CX\neq 0\),则转移
    • 功能等价:DEC CX;JNZ 标号
  • 格式:LOOPE/LOOPNE

JCXZ条件转移指令

  • 格式:JCXZ 标号
  • 功能:当CX=0时,转向标号

子程序调用和返回指令

CALL过程调用

  • 格式:CALL 子程序/地址表达式
  • 功能:
    • 保护断点:将当前断点压入堆栈
    • 转入子程序:将子程序段的入口地址送入IP(/CS)
  • 调用方式与跳转指令类似:

RET子程序返回指令

  • 格式:RET [n]
  • 功能:返回主程序。根据子程序的属性Near、Far决定
    • 段内返回:POP IP
    • 段间返回:POP IP;POP CS
  • n表示返回后执行SP=SP+n
  • CALLRET的类型必须一致

中断指令

[!相关概念] - 中断:计算机暂停现行程序的运行,转去执行另一程序以处理发生的时间,处理完毕后又自动返回原来的程序继续运行 - 中断类型: - 外部中断:可/不可屏蔽中断 - 内部中断:除法错误/溢出/单步调试/INT n - 中断服务程序:处理中断的子程序 - 中断向量:中断子程序的入口地址 - 中断向量表:存放在00000H地址的四字节表格 - 中断类型码:给中断向量的一个编号 - 中断向量表的查看:debug

INT中断调用指令

  • 格式:INT n
  • 功能:调用n号中断子程序
  • 操作:
    • PUSHF; PUSH CS;PUSH IP
    • 取得中断向量,转入

IRET中断返回指令

  • 格式:IREAT
  • 操作:POP IP;POP CS;POPF

DOS 21H号中断的使用

  • 调用21H的功能是由AH上的数据决定的
    • 从键盘读入一个字符
      MOV AH, 1/8; 1回显/8不回显
      INT 21H;
      
      • 键入字符的ASCII码存入AL
    • 显示一个字符到屏幕
      MOV AH, 2;
      MOV DL, ASCII
      INT 21H;
      
    • 显示一个字符串到屏幕
      MOV AH, 9
      LEA DX, STRING
      INT 21H
      
      • 字符串要求以$结束(提前出现则提前结束)
    • 从键盘读入一个字符串到屏幕
      MOV AH, 0AH
      LEA DX, STRING
      INT 21H
      

CPU控制指令

NOP空操作

  • 与`XCHG AX, AX相同
  • 用途:
    • timer
    • place holder

HLT暂停指令

  • 功能:
    • 使CPU进入暂停状态,直到系统复位或发生外部中断
    • 应用程序一般不使用

LOCK封锁前缀

  • 功能:
    • 用于多处理器系统,使当前处理器锁住总线,以保证当前指令为原子操作
    • 当目的操作数为内存操作数时,为了完成“读-修改-写内存”操作不被打断