80x86指令系统

指令格式
1.指令的书写格式
  标号: 指令助记符 操作数  ; 注释
2.操作数的3种形式:
 立即操作数:指令的操作数是立即数,并直接出现在指令中。
 寄存器操作数:操作数是寄存器的值,指令中使用寄存器名。
 内存操作数:操作数是某个内存单元的值,指令中给出有效地址EA,段地址在某个段寄存器中。
8086指令的操作数形式
1.立即数: 8位或16位立即数。
2.寄存器操作数:
  8位/16位通用寄存器和段寄存器(除了FS和GS)。
3.内存操作数
   包括下列几种形式。
 Variable 或 [Variable]
 [reg]
 disp[reg]
 [base][index]
 disp[base][index]
?***说明:
    Variable是变量名或变量名 ± 整数表达式。
    reg为BX、BP、SI、DI。
    disp可以是常量或变量,汇编后为一个常数,若是变量,则取其偏移地址。
    base为BX或BP,index为SI或DI。
    有效地址为各项之和。如disp[base][index]形式,EA = base + index + disp。
    若使用了BP,则隐含段地址在SS,否则在DS。
    当段地址不在隐含的段寄存器时,可使用段超越前缀,形式为:段寄存器名:
32位CPU扩展的操作数形式 
1.立即数: 32位立即数。
2.寄存器操作数: 32位通用寄存器以及FS和GS。
3.内存操作数
   包括下列几种形式。
 [base]
 disp[base]
 [base][index]
   disp[base][index]
 [index*n]
 disp[index*n]
  [base][index*n]
   disp[base][index*n]
***说明:
   base、index为任一32位通用寄存器(index不能取ESP)。
   n为比例因子,取1、2、4或8。
   若包含base且base为EBP或ESP,则隐含段地址在SS;否则,隐含段地址在DS。
   若在16位CPU上编程,则不能使用这些寻址方式。
指令系统
为了描述方便,采用下列符号约定:
dest —  目的操作数
src —  源操作数
oprdn —  第n个操作数,如oprd1, oprd2, oprd3
=  —  赋值
/ —  或者
reg8 —  8位通用寄存器AH/AL/BH/BL/CH/CL/DH/DL
reg16 —  16位通用寄存器AX/BX/CX/DX/SI/DI/BP/SP
reg32 —  32位通用寄存器EAX/EBX/ECX/EDX/ESI/EDI/EBP/ESP
reg —  reg8/reg16/reg32
seg —  段寄存器CS/DS/SS/ES/FS/GS
mem8 —  8位内存操作数
mem16 —  16位内存操作数
mem32 —  32位内存操作数
mem —  mem8/mem16/mem32
mem64 —  64位内存操作数
imm8 —  8位立即数
imm16 —  16位立即数
imm32 —  32位立即数
imm —  imm8/imm16/imm32
数据传送指令
1. MOV ( Move ):传送
   一般形式:
 MOV dest, src ; dest = src。将源操作数src复制到目的操作数dest,src不变。
   语法格式:
 MOV reg/mem/seg, reg/mem/seg/imm
    对标志位的影响:无。
   说明:
 dest与src不能作如下搭配:
  MOV mem, mem ; 错误
  MOV seg, seg  ; 错误
  MOV seg, imm  ; 错误
 dest不能是CS。
 dest与src必须类型匹配,即同时是字节、字或双字类型。
2. XCHG ( Exchange ):交换
一般形式:
 XCHG oprd1, oprd2 ; 交换oprd1与oprd2的内容
语法格式:
 XCHG reg/mem, reg/mem
    对标志位的影响:无。
说明:
oprd1与oprd2不能作如下搭配:
 XCHG mem, mem ; 错误
oprd1与oprd2类型必须匹配。、
【例】  
 xchg ebx, edx
 xchg [ebp][eax*4], edx
3. LEA (Load Effective Address ) :装入有效地址
 语法格式:
  LEA reg16, mem ; reg16 = mem的有效地址 
 对标志位的影响:无。
【例】设BX = 5678H,EAX = 1,EDX = 2。
  lea si, 2[bx]  ; 执行后,SI = 567AH
  lea si, 2[eax][edx] ; 执行后,SI = 5
4.  LDS、LES
 语法格式:
   LDS   reg16, mem32 ; reg16 = mem32的低字,DS = mem32的高字
      LES    reg16, mem32 ; reg16 = mem32的低字,ES = mem32的高字
 对标志位的影响:无。
5.  堆栈操作指令
 80x86系统的堆栈具有如下特点:
堆栈是在内存的堆栈段中,具有“先进后出”的特点。
堆栈只有一个出入口,即当前栈顶。当堆栈为空时,栈顶和栈底指向同一内存单元。
堆栈有两个基本操作:PUSH(进栈)和POP(出栈)。PUSH操作使栈顶向低地址方向移动,而POP操作则刚好相反。
堆栈操作只能以字或双字为单位。
SS:SP指向栈顶。
   (1)PUSH与POP:进栈与出栈
    语法格式:
 PUSH reg16/seg/mem16/ reg32/mem32
         POP  reg16/seg/mem16/ reg32/mem32  ; 操作数不能是CS
 PUSH imm    ; 286新增
    功能描述:
 PUSH指令(16位):
  SP = SP - 2
  SS:[SP] = 16位操作数
 POP指令(16位):
  16位操作数 = SS:[SP]
  SP = SP + 2
 PUSH指令(32位):
  SP = SP - 4
  SS:[SP] = 32位操作数
 POP指令(32位):
  32位操作数 = SS:[SP]
  SP = SP + 4
    对标志位的影响:无。
  (2)PUSHF与POPF:标志寄存器进栈和出栈
   语法格式:
  PUSHF  ; FLAGS进栈
  POPF  ; 栈顶字出栈到FLAGS
   对标志位的影响:只有POPF指令会以弹出值设置标志寄存器。
  
   【例】设SP = 100H, EBX = 12345678H, 给出下列指令依次执行后的结果。
  push bx ; ss:[00ffh] = 56h, ss:[00feh] = 78h, sp = 0feh
  pop ax ; ax = 5678h, sp = 100h
  push ebx ; ss:[00feh] = 1234h, ss:[00fch] = 5678h, sp = 0fch
  pop ax ; ax = 5678h, sp = 0feh
  pop ax ; ax = 1234h, sp = 100h
  
    【例】交换AX与CX的值。
  push ax
  push cx
  pop ax
  pop cx
6.  标志寄存器传送指令
(1)LAHF(Load AH from Flags)
 语法格式:
  LAHF ; AH = FLAGS的低8位
 对标志位的影响:无。
?
(2)SAHF(Store AH into Flags)
 语法格式:
  SAHF ; FLAGS的低8位 = AH
 对标志位的影响:由新装入值确定。

符号扩展与零扩展指令
 对标志位的影响:无。
(1)CBW、CWD、CWDE与CDQ
 语法格式:
  CBW ; AL符号扩展为AX
  CWD ; AX符号扩展为32位数DX:AX
  CWDE ; AX符号扩展为EAX;386新增
  CDQ ; EAX符号扩展为64位数EDX:EAX;386新增
【例】设AL = 0FEH,给出依次执行下列指令后的结果。
  cbw ; ax = 0fffeh
  cwd ; dx = 0ffffh, ax不变,即dx:ax = -2
  cwde ; eax = 0fffffffeh(-2)
  cdq ; edx = 0ffffffffh, eax不变,即edx:eax = -2
(2)MOVSX
      一般形式:
  MOVSX dest, src ; src符号扩展为dest;386新增
      语法格式:
   MOVSX reg16, reg8/mem8
  MOVSX reg32, reg8/mem8/reg16/mem16
      功能描述:MOVSX是CBW、CWD和CWDE的一般形式,用来将8位数符号扩展为16位或32位数,或者将16位数符号扩展为32位数。
     【例】 CBW和CWDE的功能可由MOVSX指令实现。
  movsx ax, al  ; 等价于cbw
          movsx   eax, ax  ; 等价于cwde
          movsx   eax, al ; 等价于顺序执行cbw与cwde
(3)MOVZX
      一般形式:
  MOVZX dest, src ; src零扩展为dest;386新增
     语法格式:
   MOVZX reg16, reg8/mem8
  MOVZX reg32, reg8/mem8/reg16/mem16

8.  XLAT(Translate):换码
   语法格式:
  XLAT ; AL = DS:[ BX +AL ]
   功能描述:将DS:BX所指内存区中、由AL指定位移处的一个字节赋给AL。
   对标志位的影响:无。
 
算术指令
1. 加法
     一般形式:
 ADD dest, src ; dest = dest + src
 ADC dest, src ; dest = dest + src + CF
 INC dest ; dest = dest + 1
     语法格式:
 ADD reg/mem, reg/mem/imm
 ADC reg/mem, reg/mem/imm
 INC reg/mem
      对标志位的影响:
          ADD、ADC:按一般规则影响CF、OF、SF和ZF。
          INC:不影响CF,其它同ADD。
     说明:ADD与ADC的2个操作数必须类型匹配,且不能同时是内存操作数。
2. 减法
     一般形式:
 SUB dest, src ; dest = dest – src
 SBB dest, src ; dest = dest - src – CF
 CMP dest, src ; dest – src。 与SUB的区别在于,不将减法结果存入dest。
 DEC dest ; dest = dest - 1
 NEG dest ; dest = 0 – dest
     语法格式:
 SUB reg/mem, reg/mem/imm
      SBB reg/mem, reg/mem/imm 
 CMP reg/mem, reg/mem/imm 
 DEC reg/mem
 NEG reg/mem
      对标志位的影响:
         SUB、SBB、CMP、NEG:按一般规则影响CF、OF、SF和ZF。CF表示借位。
       DEC:不影响CF,其它同SUB。
       说明:2个操作数必须类型匹配,且不能同时是内存操作数。
3. 乘法
(1)MUL(Unsigned Multiplication):无符号乘法
一般形式:
 MUL src 
语法格式:
 MUL reg8/mem8 ; AX = AL × src
 MUL reg16/mem16 ; DX:AX = AX × src
 MUL reg32/mem32 : EDX:EAX = EAX × src
对标志位的影响:若8位×8位、16位×16位或32位×32位的结果分别能由8、16或32位容纳(即结果的高一半为0),则CF = OF = 0,否则,CF = OF = 1;其余标志无定义。
说明:由于2个n位数的乘积可能需要2n位,因此,若操作数是8位,则结果为16位;同样,16位操作数相乘结果为32位,32位数相乘结果为64位。
 (2)IMUL(Integer Multiplication):带符号乘法
一般形式:
 IMUL src 
语法格式:
 IMUL reg8/mem8 ; AX = AL × src。执行带符号乘法,下同。
 IMUL reg16/mem16 ; DX:AX = AX × src
 IMUL reg32/mem32 : EDX:EAX = EAX × src
对标志位的影响:若结果的高一半为低一半的符号扩展,则CF = OF = 0,否则,CF = OF = 1;其余标志无定义。
说明:由于2个n位数的乘积可能需要2n位,因此,若操作数是8位,则结果为16位;同样,16位操作数相乘结果为32位,32位数相乘结果为64位。
【例】对于同一个二进制数,采用 MUL与IMUL执行的结果可能不同。设AL = 0FFH,BL = 1,分别执行下列指令,会得出不同结果。
 mul bl ; ax = 0ffh(255)
 imul bl ; ax = 0ffffh(-1)
4. 除法
一般形式:
 DIV src ; 无符号数除法
 IDIV     src ; 带符号数除法
语法格式:
 DIV reg/mem  
  IDIV reg/mem  
功能描述:
    src是8位:AX÷src,结果商在AL、余数在AH。
         src是16位:DX:AX÷src,结果商在AX、余数在DX。
    src是32位:EDX:EAX÷src,结果商在EAX、余数在EDX。
对标志位的影响:无定义。
5.十进制调整指令
(1)压缩BCD码调整指令
语法格式:
 DAA ; 调整AL中的和为压缩BCD码
 DAS ; 调整AL中的差为压缩BCD码
功能描述:
      DAA:通常先执行ADD/ADC指令,将2个压缩BCD码相加,结果存放在AL中。然后使用该指令将AL调整为压缩BCD码格式。
      DAS:通常先执行SUB/SBB指令,将2个压缩BCD码相减,结果存放在AL中。然后使用该指令将AL调整为压缩BCD码格式。
对标志位的影响:OF不确定;CF反映压缩BCD码相加/相减的进位/借位状态;按一般规则影响SF和ZF。
说明:若使用DAA/DAS指令,则参加加法/减法运算的操作数应该是压缩BCD码。如果将任意2个二进制数相加/减,然后调整,将得不到正确结果。
DAA的调整算法如下:
if  ( AL低4位 > 9  或  AF = 1)  then
 AL = AL + 6;
         AF = 1 ;
endif
if  ( AL高4位 > 9  或  CF = 1 )  then
         AL = AL + 60H;
         CF = 1;
     endif
DAS的调整算法如下:
if  ( AL低4位 > 9  或  AF = 1 )  then
         AL = AL – 6;
         AF = 1;
endif
if  ( AL高4位 > 9  或  CF = 1 )  then
         AL = AL - 60h;
         CF = 1;
endif
(2)非压缩BCD码调整指令
语法格式:
 AAA   ; 调整AL中的和为非压缩BCD码
  ; 调整后,AL高4位 = 0,AH = AH + 产生的CF
 AAS ; 调整AL中的差为非压缩BCD码
  ; 调整后,AL高4位 = 0,AH = AH - 产生的CF
 AAM   ; AH = AX div 10,AL = AX mod 10
 AAD   ; AL = AH × 10 + AL,AH = 0
功能描述:
      AAA:通常先执行ADD/ADC指令,以AL为目的操作数,将2个非压缩BCD码(高4位无关)相加。然后使用AAA将AL调整为非压缩BCD码格式,且高4位 = 0,同时将调整产生的进位加到AH中。
      AAS:通常先执行SUB/SBB指令,以AL为目的操作数,将2个非压缩BCD码(高4位无关)相减。然后使用AAS将AL调整为非压缩BCD码格式,且高4位 = 0,同时将调整产生的借位从AH中减去。
      AAM与AAD:略。
对标志位的影响:
     AAA与AAS:CF反映非压缩BCD码加/减的进位/借位;OF、SF和ZF不确定。
AAA的调整算法如下:
if  ( AL低4位 > 9 或  AF = 1 )  then
    AL = AL + 6;
         AH = AH + 1;
         AF = 1;              
         CF = 1;            
else
         AF = 0;              
         CF = 0;             
endif
AL = AL AND 0FH    ;    AL高4位清0
AAS的调整算法如下:
if  ( AL低4位 > 9 或 AF = 1)  then
        AL = AL – 6;
        AH = AH – 1;
        AF = 1;
        CF = 1;
else
        AF = 0;      
        CF = 0;     
endif
AL = AL AND 0FH    ; AL高4位清0