8086指令系统

首先定义出要用的符号

OPRD泛指各种类型的操作数
mem存储器操作数
acc累加器操作数
dest目标操作数
src源操作数
disp8位或16位偏移量,可用符号地址表示。
DATA8位或16位立即数
port输入输出端口
[ ]表示存储器操作数,方括号内表示数据的偏移地址

数据传送指令

数据传送指令按功能分为四小类:通用数据数据传送指令,目标地址传送指令,标志传送指令,输入输出指令。

通用传送指令

通用数据传送指令包括一般传送指令mov,堆栈操作指令push或pop,交换指令xchg,查表转化指令xlat和字位扩展指令。

一般传送指令MOV

指令格式及操作:mov dest,src,这里,dest表示目标操作数,src表示源操作数。指令的功能是将一个操作数从源地址传送到目标地址,而源地址中的数据保持不变。

指令中的操作数可以是8位,也可以是16位,一次传送的数据到底是字节还是字取决于指令中涉及的寄存器是8位还是16位的。

(1)寄存器与寄存器或寄存器与段寄存器之间的传送,例如

mov bx,si ;将变址寄存器si中的内容送到基址寄存器bx
mov ds,ax ;将累加器ax中的内容送到段寄存器ds
mov al,cl ;将通用寄存器cl中的内容送到al

(2)寄存器与存储器之间的传送。mov指令可以在寄存器和存储器之间进行数据传送,若传送的是字操作符,那么 将对连续两个存储器进行存取,且寄存器的高8位对应存储器的高地址单元,寄存器的低8位对应存储器的低地址单元。

例如:若有DS=6000H,SS=8000H,AX=1234H,BX=1200H,DI=0383H,BP=1020H则有

mov [bx],ax ;将ax的内容送到内存单元,其中[61200H]=34H,[61201H]=12H
mov cl,[bp][di] ;将堆栈段中偏移地址为BP+DI=13A3H单元的内容送到CL,即物理地址为813A3H单元的内容送到CL
mov ax,[6000H] ;将DS段的6000H和6001H两个单元的内容送ax

(3)立即数到寄存器的传送

mov al,5 ;将立即数5送到累加器al
mov bx,3078h ;将立即数3078h送寄存器bx

(4)立即数到存储器的传送

mov byte ptr[bp+si],5 ;将5送到堆栈段中偏移地址为BP+SI所指的单元中。
mov word ptr[bx],1005h ;将1005h送数据段中偏移地址为BX和BX+1两单元。

(5)存储器与段寄存器之间的传送

mov ds,[1000h] ;将数据段中偏移地址为1000h字单元内容送到数据段寄存器ds
mov [bx],es ;将附加段寄存器es内容送到数据段中bx所指向的字单元

指令对操作数的要求

  1. mov指令中两个操作数字长必须相同,两个操作数可同为字节数或同为字操作数。

  2. 两个操作数不能同时为存储器操作数,若要在两个存储器单元之间进行数据传送,需用两条mov指令实现。

  3. 不能用立即数直接给段寄存器赋值,要实现此功能,需使用两条mov指令。

  4. 两个操作数不能同时为段寄存器,同样,要实现段寄存器到段寄存器的数据传送,需要两条mov指令。

  5. 一般情况下,指令指针IP及代码段寄存器的内容不通过mov指令修改,即它们不能作为目标操作数,但可以作为源操作数。

  6. 虽然许多指令的执行都对状态寄存器FLAGS的标志位产生影响,但通常情况下,FLAGS整体不能作为操作数。

例如:把内存中首地址为MEM1的200个字节送到首地址为MEM2的区域中。

题目分析:两个内存单元中的数据传送需要两条MOV指令实现,通过循环实现。

	  mov si,offset mem1 ;源数据块首地址(偏移地址)送入SI
	  mov di,offset mem2 ;目标首地址送入DI
	  mov cx,200 ;数据库长度送入cx,即=循环次数cx
next: mov al,[si] ;源数据块中当前字节送入AL
	  mov [di],al ;AL内容送目标地址,完成一个字节的传送
	  inc si ;SI+1,修改原地址指针
	  inc di ;DI+1,修改目标地址指针
	  dec cx ;CX-1,修改循环次数
	  jnz next ;若循环次数CX不等于0,则转移到next处
	  hlt ;暂停
堆栈操作指令PUSH和POP

(1)堆栈的概念。堆栈是内存中一个特定的区域,用以存放寄存器或存储器中暂停不用又必须保存的数据。它在内存中所处的段称为堆栈段,其段地址放在堆栈寄存器SS中。可以将堆栈看作是一个小存储器,但不能任意存取,必须遵守以下规则:

  1. 堆栈的存取每次必须是一个字(16位),即堆栈指令中的操作数必须是16位,即堆栈指令中的操作数必须是16位,而且只能是寄存器或存储器操作数,不能是立即数。
  2. 向堆栈中存放数据时,总是从高地址向低地址方向增长,而从堆栈取数据时则方向正好相反。
  3. 堆栈段在内存中的位置由SS决定,堆栈指针SP总是指向栈顶指针,即SP的内容等于当前栈顶的偏移地址。所谓栈顶是指当前可用堆栈操作指令进行数据交换的存储单元。在压入操作数之前,SP先减2,每弹出一个字,SP+2。
  4. 对堆栈的操作遵循“后进先出”的原则。

在程序调用时,堆栈主要应用于子程序调用、中断响应等操作时的参数保护,也可用于实现参数传递。

(2)堆栈操作指令。堆栈操作指令共有两条:压入堆栈指令PUSH和弹出堆栈指令POP。其格式为:

PUSH src
POP dest

指令中的操作数src和dest必须是字操作数(16位),它们可以是: 16位的通用寄存器或段寄存器,存储器单元。

push ax ;通用寄存器内容压入堆栈
push word ptr[data+si] ;数据段中两个连续存储单元内容压入堆栈
pop ds ;从栈顶弹出一个字到段寄存器
pop word ptr[bx] ;从栈顶弹出一个字到数据段两个连续内存中。

(3)堆栈指令的执行过程

  1. 压栈指令PUSH OPRD。PUSH指令是将指令中指定的字操作数压入堆栈。指令执行的过程为SP-2->SPOPRD高八位->[SP+1]OPRD低8位->[SP]
  2. 出栈指令POP OPRD。POP指令是将当前栈顶的一个字送到指令的目标地址,并紧接着修改堆栈指针,以使SP指向新的栈顶位置。指令的执行过程为:[SP]->OPRD低8位[SP+1]->OPRD高8位SP+2->SP

在程序中,PUSH和POP指令一般成对出现,且执行顺序相反,以保持堆栈原有状态,当然,在必要时也可通过修改SP的值来恢复堆栈原有状态。

堆栈除在子程序调用和响应中断时用于保护断点地址外,还可在需要时对某些寄存器内容进行保存。例如用CX寄存器同时作为两重循环嵌套的寄存器,可先将外循环计数值送CX,当内循环开始时将CX中的外循环计数值压入堆栈保存,然后把内循环计数写入CX,内循环完成后再将外循环计数值从堆栈中弹出CX。

交换指令XCHG

指令格式及操作:xchg oprd1,oprd2

交换操作就是将源地址与目标地址中的内容进行互换,即将源操作数送到目标操作数,同时将目标操作数传送源操作数。

交换指令对操作数的要求:

  1. 源操作数和目标操作数可以是寄存器或存储器,但不能同时为存储器。
  2. 不能为段寄存器操作数,即段寄存器的内容不能参加交换
  3. 两个操作数字长必须相同,可以是字节交换,也可以是字交换。

例如:设DS=2000H,SI=0230H,DL=88H,[20230H]=44H,执行指令xchg [si],dl,执行结果:[20230H]=88H,DL=44H。DL的内容与[20230H]的内容进行交换。

查表转换指令XLAT

XLAT是一条字节的查表转换指令,可以根据表中元素的序号查出表中相应元素的内容。

预先将要查找的代码排成一个表放在内存某区域中,指令要求将表的首地址(偏移地址)送寄存器BX,要查找的元素的序号送入AL(表中第一个元素的序号为0,然后依次为1,2,3)。执行XLAT指令后,表中指定序号的元素被存入AL。

指令格式:XLAT ;将偏移地址为BX+AL所指单元的内容送到AL中,或XLAT src_table ;src_table表示要查找的表的首地址

例如:在内存的数据段中存放有一张数值为0~9的ASCII码转换表,首地址为Hex_table,现要把数值8转换为对应的ASCII码,可用以下几条指令实现

LEA BX,Hex_table ;BX<-表首偏移地址 LEA指令将存储器操作数mem的4位16进制偏移地址送到指定的寄存器。
MOV AL,8 ;AL<-8
XLAT ;查表转换

结果为AL=38H,为8所对应的ASCII码。由于要查找元素的序号放在AL中,所以表格的最大长度不超过256个字节。

输入输出指令

输入输出指令是专门面向输入输出端口进行读写的指令,共有两条:IN和OUT,输入指令用于从I/O端口读数据到AL或AX中,而输出指令则把AL或AX的内容写出到I/O。在8088指令系统中,允许用两种形式表示端口地址:直接寻址,寄存器间接寻址。

  1. 直接寻址:指令中的I/O端口地址为8位,此时允许寻址256个端口,端口地址范围为0~FFH。
  2. 寄存器间接寻址:端口地址为16位,由DX寄存器指定,可寻址64K个端口,地址范围为0~FFFFH。

(1)输入指令IN:指令格式为in acc,port ;直接寻址,port为用8位立即数表示的端口地址in acc,DX ;间接寻址,16位端口由DX给出

IN指令从端口输入一个字节到AL或输入一个字到AX中。

(2)输出指令OUT:指令格式为out port,acc ;直接寻址,port为8位立即数表示的端口地址out dx,acc ;间接寻址,16位端口地址由DX给出

OUT指令将AL或AX的内容输出指定端口。

注意;采用间接寻址的IN/OUT指令只能用DX寄存器作为间址寄存器。

取偏移地址指令

指令格式:lea reg16,mem,lea指令将存储器操作数mem的16位偏移地址送到指定的寄存器。

lea bx,buffer ;将内存单元buffer的偏移地址送bx
mov al,[bx] ;取出buffer中的第一个数据送al
mov ah,[bx+1] ;取出buffer中的第二个数据送ah

例如:若设BX=1000H,DS=6000H,[61050H]=33H,[61051H]=44H。比较以下两条指令的执行结果。

lea bx,[bx+50H] 
mov bx,[bx+50H]

第一条执行后BX=1050H,第二条指令执行后BX=4433H。

其他传送指令

指令类型汇编格式指令的操作示例
字位扩展指令CBW将AL中的字节数扩展为字,并存放在AX中,扩展的原则是:将符号位扩展到整个高位MOV AL,8EH
CBW
;AX=FF8EH
字位扩展指令CWD将AX的字扩展为双字,扩展后高16位放在DX中,扩展的原则与CBW指令相同。MOV AX,438H
CBW
;AX=438EH.DX=0000H
远地址传送指令LDS reg16,mem32mem32为内存中连续4个单元的首地址,指令将[mem32]和[mem32+1]单元内容送入reg16,将[mem32+2]和[mem32+3]单元的内容送DS。设1234H为首的4个单元内容分别为11H,22H,00H,90H,则执行完lds si,[1234H],SI=2211H,DS=9000H

算术运算指令

算术运算涉及运算结果是否溢出,无符号数和有符号数的表示方法、数的可表示范围及溢出标志都不一样。有符号数的溢出是一种出错,而无符号数溢出则不能简单的认为是出错,也可看作是向更高位的进位。它们的判断标志分别为CF和OF。

加法指令

普通加法指令ADD

指令格式:ADD OPRD1,OPRD2,将源操作数和目标操作数相加,结果送回目标地址中。

这里,源操作数OPRD2和目标操作数OPRD1均可以是8位或16位的寄存器或存储器操作数,源操作数可以是立即数,可以是无符号数,也可以是带符号数。

以下指令是合法的

add cl,20h
add dx,[bx+si]

以下指令是非法的

add [si],[bx]
add ds,ax

ADD指令的执行对全部6个状态标志位都会产生影响。

  1. AF=1 表示 D 3 D_3 D3 D 4 D_4 D4有进位。
  2. CF=0 表示最高位向前无进位。
  3. OF=1 表示若为有符号数加法,其运算结果产生溢出。
  4. PF=0 表示8位的运算结果中,“1”的个数为奇数。
  5. SF=1 表示运算结果的最高位为“1”
  6. ZF=1 表示运算结果不为“0”
带进位的加法指令ADC

指令格式:ADC OPRD1,OPRD2,ADC指令与ADD指令功能、格式及对标志位的影响上都基本相同。只是CF也要参与运算。

加1指令INC

指令格式:INC OPRD,INC指令是将指定操作数的内容加1,再送回操作数。这里的操作数OPRD可以是寄存器或存储器数,可以是8位,也可以是16位数,但不能是段寄存器,也不能是立即数。INC指令不影响CF标志,但对其他5个标志位AF,OF,PF,SF,ZF会产生影响。

减法运算

8086/8088共有5条减法指令,不考虑借位的普通减法指令SUB,考虑借位的减法指令SBB,减1的指令DEC,求补指令NEG,比较指令CMP。

指令名指令格式指令功能注意
SUBSUB OPRD1,OPRD2目标数减去源操作数,并将结果送入目标操作数的地址。不考虑借位。对操作数和影响标志位与ADD相同。
SBBSBB OPRD1,OPRD2目标操作数减去源操作数和CF的值,并将结果送目标操作数的地址。其对标志位的影响与SUB相同。
DECDEC OPRD将操作数的值减1,结果送回操作数地址。其对标志位的影响与INC相同。
NEGNEG OPRD用0减去操作数OPRD,结果返回操作数地址。执行后,一般CF=1,除非给定操作数为0,则CF=0
CMPCMP OPRD1,OPRD2用目标操作数减去源操作数,改变标志位情况判断大小ZF=1,相等。ZF=0,不相等。
对两个无符号数,CF=0,则被减数大于减数。
对有符号数, O F ⊕ S F = 0 OF \oplus SF=0 OFSF=0,被减数大于减数。

乘法指令

MUL OPRD

指令的操作

  1. 字节乘法 A X ← O P R D × A L AX \leftarrow OPRD \times AL AXOPRD×AL
  2. 字乘法 D X : A X ← O P R D × A X DX:AX \leftarrow OPRD \times AX DX:AXOPRD×AX

源操作数可以是8位或16位的寄存器或存储器,乘法指令要求操作数字长相等,且不能为立即数。

除法指令

DIV OPRD

指令的操作

  1. 字节除法 A L ← A X / O P R D , A H ← A X % O P R D AL \leftarrow AX/OPRD,AH \leftarrow AX \% OPRD ALAX/OPRD,AHAX%OPRD

  2. 字除法 A X ← D X : A X / O P R D , D X ← D X : A X % O P R D AX \leftarrow DX:AX/OPRD,DX \leftarrow DX:AX \% OPRD AXDX:AX/OPRD,DXDX:AX%OPRD

逻辑运算和移位指令

逻辑运算

指令名指令格式指令功能
ANDAND OPRD1,OPRD2OPRD1 = OPRD1 & OPRD2
OROR OPRD1,OPRD2OPRD1 = OPRD1 | OPRD2
NOTNOT OPRDOPRD = !OPRD
XORXOR OPRD1,OPRD2 O P R D 1 = O P R D 1 ⊕ O P R D 2 OPRD1 = OPRD1 \oplus OPRD2 OPRD1=OPRD1OPRD2

非循环移位指令

指令名指令格式指令功能
SALSAL OPRD,1 SAL OPRD,CLSAL指令的操作将目的操作数的内容CL中所指定的位数。每左移一位,左边的值存入CF。
SARSAR OPRD,1 SAR OPRD,CLSAR是将目标操作数视为有符号数,最高位不是补零,而是保持不变。右边的值存入CF。
SHLSHL OPRD,1 SHL OPRD,CLSHL指令的操作将目的操作数的内容CL中所指定的位数。每左移一位,左边的值存入CF。
SHRSHR OPRD,1 SHR OPRD,CLSHR指令的操作将目的操作数的内容CL中所指定的位数。每右移一位,右边的值存入CF。

串操作指令

所有串操作指令都具有以下特点

  1. 源串默认为数据段,即段基地址在DS中,但允许重设,偏移地址用SI寄存器指定,即源串指针为DS:SI。
  2. 目标串默认在ES附加段中,不允许段重设。偏移地址用DI寄存器锁定,即目标指针为ES:DI。
  3. 串长度值放在CX寄存器中。
  4. 串操作指令本身可实现地址指针的自动修改。
指令名指令格式指令功能
MOVSMOVS OPRD1,OPRD2OPRD1为目标地址,OPRD2为源地址,指令将源地址字节或字传送给到目标地址中。
MOVSBMOVSB源串在数据段,偏移地址在SI中,目标串在附加段,偏移地址在DI中。一次完成一个字节的传送。
MOVSWMOVSW源串在数据段,偏移地址在SI中,目标串在附加段,偏移地址在DI中。一次完成一个字的传送。
CMPSCMPS OPRD1,OPRD2将源串地址与目标串地址的数据按字节或字进行比较,结果反应到标志位。
CMPSBCMPSB一次完成一个字节比较
CMPSWCMPSW一次完成一个字比较

程序控制指令

无条件转移指令JMP

指令格式:JMP LABEL,LABEL是一个标号,也称为符号地址,表示转移的目的地。

JMP指令的操作是无条件地使程序转移到指定的目标位置,并从该地址开始执行新的程序段。

条件转移指令JCC

JCC指令中文含义检查符号位
JZ/JE若为0则跳转;若相等则跳转ZF=1
JNZ/JNE若不为0则跳转;若不相等则跳转ZF=0
JS若为负则跳转SF=1
JNS若为正则跳转SF=0
JP/JPE若1出现次数为偶数则跳转PF=1
JNP/JPO若1出现次数为奇数则跳转PF=0
JO若溢出则跳转OF=1
JNO若无溢出则跳转OF=0
JC/JB/JNAE若进位则跳转;若低于则跳转;若不高于等于则跳转CF=1
JNC/JNB/JAE若无进位则跳转;若不低于则跳转;若高于等于则跳转;CF=0
JBE/JNA若低于等于则跳转;若不高于则跳转ZF=1或CF=1
JNBE/JA若不低于等于则跳转;若高于则跳转ZF=0或CF=0
JL/JNGE若小于则跳转;若不大于等于则跳转SF != OF
JNL/JGE若不小于则跳转;若大于等于则跳转;SF = OF
JLE/JNG若小于等于则跳转;若不大于则跳转ZF != OF 或 ZF=1
JNLE/JG若不小于等于则跳转;若大于则跳转SF=0F 且 ZF=0

循环控制指令

LOOP指令

指令格式:LOOP LABEL,指令的执行是先将CX减1,再判断CX是否为0,若CX不为0,则转至目标地址继续循环。

LOOPZ指令

指令格式:LOOPZ LABEL,指令的执行先将CX减1,再根据CX的值及ZF的值判断是否继续循环。继续循环的条件是CX不为0,ZF为1。若CX=0或ZF=0,退出循环。

中断指令

INT指令

指令格式:INT n,CPU根据n计算中断向量的地址,然后从该地址取出中断服务程序的入口地址,并转到中断服务子程序去执行。

IRET指令

IRET为中断返回指令,用于从中断服务子程序返回到被中断的程序继续执行。任何中断服务子程序无论是外部还是内部中断,其最后一条指令都是IRET指令。

处理器控制指令

CLC:清进位标志位CF。

STC:进位标志位置位。

CMC:进位标志位取反。

CLD:DF置0。

STD:DF置1。

CLI:IF置0。

STI:IF置1。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值