目录
  1. 1. 标志寄存器FLASGS
  2. 2. 数据传送指令
    1. 2.1. MOV
    2. 2.2. PUSH
    3. 2.3. POP
    4. 2.4. XCHG
    5. 2.5. LEA
    6. 2.6. 类型转换指令
      1. 2.6.1. CBW AL → AX
      2. 2.6.2. CWD AX → (DX,AX)
  3. 3. 算术指令
    1. 3.1. 加法
      1. 3.1.1. ADD
      2. 3.1.2. ADC
      3. 3.1.3. INC
    2. 3.2. 减法
      1. 3.2.1. SUB
      2. 3.2.2. DEC
      3. 3.2.3. NEG
      4. 3.2.4. CMP
    3. 3.3. 乘法
    4. 3.4. 除法
  4. 4. 逻辑指令
    1. 4.1. 逻辑运算指令
      1. 4.1.1. AND
      2. 4.1.2. OR
      3. 4.1.3. NOT
      4. 4.1.4. XOR
      5. 4.1.5. TEST
      6. 4.1.6. 注意
    2. 4.2. 移位指令
      1. 4.2.1. 算术移位(arithmetic)
      2. 4.2.2. 逻辑移位(logical)
      3. 4.2.3. 循环移位(rotate)
      4. 4.2.4. 总结
  5. 5. 串处理指令
    1. 5.1. 方向标志
    2. 5.2. 重复前缀指令REP
    3. 5.3. 相等重复前缀指令REPE(REPZ)
    4. 5.4. 不等重复前缀指令REPNE(REPNZ)
    5. 5.5. 串比较指令 CMPS
  6. 6. 控制转移指令
    1. 6.1. 无条件转移指令
    2. 6.2. 条件转移指令
      1. 6.2.1. 根据单个条件标志的设置情况转移
      2. 6.2.2. 无符号数的条件转移
      3. 6.2.3. 有符号数的条件转移
    3. 6.3. 循环指令
      1. 6.3.1. LOOP
      2. 6.3.2. 其他
    4. 6.4. 子程序调用和返回
      1. 6.4.1. 调用指令 CALL
      2. 6.4.2. 返回指令 RET
    5. 6.5. 中断的调用和返回指令
      1. 6.5.1. 中断指令 INT
      2. 6.5.2. 溢出指令 INTO
      3. 6.5.3. 中断返回指令 IRET
    6. 6.6. 中断和子程序的比较
汇编指令

标志寄存器FLASGS

  1. ZF(Zero Flag)
  • 零标志位,执行完相关指令后,其结果是否为0
  • 为0则ZF=1;不为0则ZF=0
  1. CF(Carry Flag)
  • 进位标志位,当运行结果的最高有效位有进位(加法)或借位(减法)时,进位标志置1,即CF=1;否则CF=0
  1. SF(Sign Flag)
  • 运行结果最高位为1,则SF=1,否则SF=0
  1. PF(Parity Flag)
  • 当运行结果最低字节的“1”的个数为零或者偶数时,PF=1,否则,PF=0
  1. OF(Overflow Flag)
  • 若算术运算的结果有溢出则OF=1,否则OF=0

数据传送指令

MOV

中文名:传送指令
允许以下操作:

  1. MOV 寄存器,寄存器/内存单元/段寄存器/立即数
  2. MOV 内存单元,寄存器/段寄存器/立即数
  3. MOV 段寄存器,寄存器/内存单元

不允许以下操作:
4. 两个操作数类型不一样

  • 例如源操作数是字节,而目的操作数是字
  1. 两个操作数不能都是内存单元的数
    • 主存之间的直接传送不允许
  2. 段寄存器的操作限制:
    1. 不允许直接传立即数给段寄存器

      不能直接用变量名,因为变量其实也是个立即数

    2. 不要直接改变CS值
    3. 不允许段寄存器之间的直接数据传送

PUSH

进栈操作,以一个字为例,系统自动完成两步操作:

  1. SP ⬅ SP-2 //堆栈指针减2
  2. (SP+1,SP) ⬅ SRC //将数据压入堆栈

POP

出栈操作,弹出一个字为例,系统自动完成两步操作:

  1. 操作数 ⬅ SP
  2. SP ⬅ SP+2
    功能:将栈顶内容弹至某一寄存器,段寄存器(CS除外)或存储器

XCHG

XCHG OPR1, OPR2
功能:交换指令,OPR1,OPR2互换

LEA

LEA Reg,Mem
功能:将一个内存变量的有效地址送给指定的寄存器

类型转换指令

CBW AL → AX

  • 执行的操作:
    • 若(AL)的最高有效位为0则 AH = 00H
    • 若(AL)的最高有效位为1则 AH = 0FFH

CWD AX → (DX,AX)

  • 执行操作:
    • 若(AX)的最高有效位为0,则(DX)= 0000H
    • 若(AX)的最高有效位为1,则(DX)= 0FFFFH

算术指令

加法

  • 重要的条件标志位:ZF,CF,SF,OF
    • ZF,SF设置较为简单
    • CF:最高有效位是否有进位
    • OF:两个操作数符号(最高有效位)相同,结果与之相反则OF=1;否则OF=0
  • INC对符号位无影响

ADD

功能:DST ⬅ DST+SRC

ADC

功能:带进位的加法,DST ⬅ DST+SRC+CF

INC

功能:OPR ⬅ OPR+1

减法

  • CF:减数 > 被减数,此时有借位,则CF=1;否则CF=0
  • OF:两个数符号(最高有效位)相反,而结果符号与减数相同,则OF=1;否则OF=0
  • DEC对符号位无影响

SUB

功能:功能:DST ⬅ DST-SRC

DEC

功能:OPR ⬅ OPR-1

  • 对CF标志位无影响

NEG

功能:求补,每位求反(包括符号位)后加1

  • OPR ⬅ 0 - OPR
  • 因此,除了OPR=0,其他情况CF=1

CMP

功能:得到(OPR1-OPR2)的结果,改变标志位ZF或CF

乘法

  • 无符号乘法:MUL SRC
  • 有符号乘法:IMUL SRC
  • 功能:
    • 若是字节数据相乘,AL和SRC相乘的结果放在AX
      • AX⬅AL*SRC
    • 若是字数据相乘,(AX)和SRC相乘得到的双字数据,高字放入DX,低字放入AX
      • DX,AX⬅AX*SRC
  • 乘法中OF,CF使用来判断相乘的结果是什么类型。

    字节相乘的结果是字节还是字。OF=CF=0为字节,OF=CF=1为字
    字相乘的结果是字还是双字。OF=CF=0为字,OF=CF=1为双字

除法

  • 无符号除法:DIV SRC
  • 有符号除法:IDIV SRC
  • 执行的操作(低位放商,高位放余数):
    • 字节操作:

      (AL)⬅(AX)/(SRC)的商
      (AH)⬅(AX)/(SRC)的余数

    • 字操作:

      (AX)⬅(DX,AX)/(SRC)的商
      (DX)⬅(DX,AX)/(SRC)的余数

  • 对标志位没影响,但也会产生溢出
  • 可能产生编号为0的内部中断:除法错中断

逻辑指令

逻辑运算指令

AND

功能:两个操作数按位与操作,结果存入操作数
用途:该指令用于清除目的操作数中与源操作数中置0位对应的位

  • DST ⬅ DST & SRC

OR

功能:两个操作数按位或操作,结果放入操作数
用途:用于设置目的操作数中与源操作数置1位的对应位

  • DST ⬅ DST | SRC

NOT

功能:按位取反

  • DST ⬅ ~DST

XOR

功能:两个操作数按位异或,将结果放入操作数

  • DST ⬅ DST⊕SRC

TEST

功能:两个操作数相与,但结果不保存,只根据其特征置条件码

  • OPR1 & OPR2

注意

  • NOT不允许使用立即数,其他4条指令至少有一个操作数必须在寄存器中
  • NOT不影响符号位,其他4条指令 将CF,OF置0 ,AF无定义,而SF,ZF,PF根据结果来设置

移位指令

  • 移位指令后面的数只能为 1,大于1的时候用cl
  • 如:shr xxx,cl;shr xxx,1

算术移位(arithmetic)

算术移位指令有:算术左移SAL和算术右移SAR

  • 指令格式为SAL/SAR OPR,CL/Imm
  • 受影响的标志位:CF、OF、PF、ZF和SF(AF无定义)
  • 功能:
    • 算术左移SAL把目的操作数的低位向高位移,空出的低位补0
    • 算术右移SAR把目的操作数的高位向低位移,空出的高位用最高位(符号位)填补
    • 算术移位指令常用于带符号数*2或/2

逻辑移位(logical)

逻辑左移SHL和逻辑右移SHR它们的指令格式如下:
SHL/SHR OPR, CL/Imm

  • 受影响的标志位:CF(移出放在CF)、OF、PF、SF和ZF(AF无定义)。
  • 逻辑左移/右移指令只有它们的移位方向不同,移位后空出的位都补0
  • 逻辑移位指令常用于无符号数*2或/2

循环移位(rotate)

循环移位指令有:

  1. 循环:左移ROL,右移ROR
  2. 带进位循环:左移RCL,右移RCR
  • 指令的格式:ROL/ROR OPR, CL/Imm
  • 受影响的标志位:CF和OF
  • 循环左移/右移指令只是移位方向不同,它们移出的位不仅要进入CF,而且还要填补空出的位。
  • 带进位循环移动将CF加入循环中

总结

无符号数:逻辑移位
有符号数:算术移位

  • 逻辑左移和算术左移一致,均把移出的放在CF,末位补0
  • 逻辑右位的方法是逻辑左移镜像
  • 算术右移移出的放在CF,但是首位补符号位,而不是补0

串处理指令

方向标志

执行串处理指令时会根据DF(direction flag)来使地址自动增加/减少

  • CLD(DF=0)增加STD(DF=1)减少

重复前缀指令REP

重复前缀指令是重复其后的字符串操作指令,重复的次数由CX来决定

  • 一般格式为:REP MOVS / STOS / LODS

相等重复前缀指令REPE(REPZ)

重复条件:CX != 0 && ZF = 1

不等重复前缀指令REPNE(REPNZ)

重复条件:CX != 0 && ZF = 0

串比较指令 CMPS

  • 语句格式:
    • CMPSB——字节串比较
    • CMPSW——字串比较
  • 功能:将SI所指的源串中的一个字节(或字)存储单元中的数据与DI所指的目的串中的一个字节(或字)存储单元中的数据相减,并根据相减的结果设置标志,但结果并不保存

控制转移指令

无条件转移指令

包括:JMP子程序调用和返回中断的调用和返回指令

条件转移指令

分为三类:

  1. 基于无符号数的条件转移指令
  2. 基于有符号数的条件转移指令
  3. 基于特殊算术标志位的条件转移指令
1
2
JXX  LABEL  ;条件满足:转移,(IP)⬅(IP)+位移量
;条件不满足,顺序执行
  • 操作数LABEL采用短转移,成为相对寻址方式
  • JXX不影响标志位,但要利用标志位。

根据单个条件标志的设置情况转移

指令助忆符 检测转移的条件 功能描述
JZ(JE) ZF=1 结果为零或相等则转移
JNZ(JNE) ZF=0 结果不为0或不等则转移
JS/JNS SF=1/SF=0 结果为负/正则转移
JO/JNO OF=1/OF=0 结果溢出/不溢出则转移
JP/JNP PF=1/PF=0 奇偶位为1/0则转移

无符号数的条件转移

  • Below,Equal,Above
指令助忆符 检测转移的条件 功能描述
JB/JNAE CF=1 小于时,或进位为1则转移
JNB/JAE CF=0 不小于,或进位为0转移
JBE/JNA CFvZF=1 小于等于则转移
JNBE/JA CF^ZF=0 不小于等于,即大于,则转移

有符号数的条件转移

  • Less,Equal,Greater
指令助忆符 检测转移的条件 功能描述
JL/JNGE SF⊕OF=1 小于则转移
JNL/JGE SF⊕OF=1 不小于,即大于等于转移
JLE/JNG ZF=1 or SF!=OF 小于等于则转移
JG/JNLE ZF=0 and SF=OF 不小于等于,即大于,则转移

循环指令

LOOP

  • 指令格式:LOOP 短标号
  • 执行过程:如果CX ≠ 0,转向“标号”所指向的指令,否则,终止循环,执行该指令的下一条指令
  • 说明:使用LOOP可以代替以下两条指令:

    DEC CX
    JNE 短标号

其他

  • 相等/为0循环指令 LOOPE/LOOPZ
  • 不相等/不为零循环指令LOOPNE/LOOPNZ

子程序调用和返回

调用指令 CALL

类似JMP指令,但是不同于JMP,CALL指令需要保存返回地址(将其入栈)

返回指令 RET

将栈内保存的地址弹出,折返调用该子程序的位置

中断的调用和返回指令

中断指令 INT

  • 一般格式:INT TYPE
  • 其中:立即数TYPE是一个0~0FFH范围内的整数。
  • 指令执行的步骤:
    1. 把标志寄存器压栈,清除标志位IF和TF;
    2. 把代码段寄存器CS和指令指针寄存器IP的内容压栈;
    3. IP ← TYPE4,CS ← TYPE4+2

溢出指令 INTO

当标志位OF为1时,引起中断。

中断返回指令 IRET

  • 当一个中断服务程序执行完毕时,CPU将恢复被中断的现场,返回到引起中断的程序中。
  • 该指令执行的过程基本上是INT指令的逆过程:
    1. 从栈顶弹出内容送入IP
    2. 再从新栈顶弹出内容送入CS
    3. 再从新栈顶弹出内容送入标志寄存器

中断和子程序的比较

  • 相同之处:暂停当前程序的执行,转而执行另一程序段,当该程序段执行完时,CPU都自动恢复原程序的执行。
  • 不同之处:
    1. 调用:子程序人为调用;中断不可预见(除了INT引起的中断)
    2. 实现方式:子程序调用是用CALL指令来实现的,但没有调用中断的指令,只有发出中断请求的事件(指令INT是发出内部中断信号,而不要理解为调用中断服务程序);
    3. 返回方式:子程序RET;中断IRET
    4. 在通常情况下,子程序是由应用系统的开发者编写的,而中断服务程序是由系统软件设计者编写的。
文章作者: EasonZzZz
文章链接: http://yoursite.com/2019/12/13/学习/汇编/汇编指令/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Nice To Meet U