• DJ 12-3 程序控制指令


    目录

    1. 无条件转移指令 JMP

    (1)段内直接转移

    (2)段内间接转移

    (3)段间直接转移

    (4)段间间接转移

    2. 条件转移指令

    3. 循环控制指令

    (1)LOOP 指令

    (2)LOOPZ/LOOPE 指令

    (3)LOOPNZ/LOOPNE 指令

    4. 过程调用和返回

    (1)段内直接调用

    (2)段内间接调用

    (3)段间直接调用

    (4)段间间接调用

    (5)返回指令 RET

    5. 中断指令

    (1)中断指令 INT

    (2)中断返回指令 IRET

    6. 处理器控制指令


    1. 无条件转移指令 JMP

    功能:无条件地使程序转移到指定的目标地址,并从该地址开始执行新的程序段。

    目标地址 = 段地址 × 16 + 段内偏移地址

    • 段内转移:CS 不变,仅改变 IP 的值。
    • 段间转移:CS、IP 寄存器的内容均发生改变。

    转移指令对 FLAGS 状态标志位没有影响。

    (1)段内直接转移

    格式:JMP  Label

    执行:IP + Disp → IP

    写法:JMP XXXXH

    Label:段内标号,又称符号地址,它表示转移的目的地。该标号在本程序所在代码段内。

    应用举例:

    指令被汇编时,汇编程序会计算出 JMP 指令的下一条指令到 NEXT 所指示的目标地址之间的位移量 Disp,即相距多少个字节单元。

    指令的操作是将 IP 当前值加上计算出的地址位移量 Disp 形成新的 IP,并使 CS 保持不变,从而使程序按新地址继续运行,即实现了程序的转移。

    (2)段内间接转移

    格式:JMP  OPRD

    执行:OPRD → IP

    OPRD:是通用寄存器或存储器根据相应的寻址方式,获得的一个 16 位操作数来作为转移目标的偏移地址。

    应用举例:

    (3)段间直接转移

    格式:JMP  FAR  PTR  Label(FAR  PTR 使 Label 成为远标号,PTR 属性修改)

    写法:JMP  XXXXH:XXXXH

    执行:段地址 → CS、偏移地址 → IP

    Label:段间标号,又称远标号,该标号在另一个代码段内。Label 直接给出汇编程序转移时需要的 16 位段地址和 16 位偏移地址,即标号所在的代码段及其位置的偏移地址。

    (4)段间间接转移

    格式:JMP  OPRD

    执行:OPRD(高 16 位) → CS、OPRD(低 16 位) → IP

    OPRD:是一个根据寻址方式得到的 32 位存储器操作数。

    因为寄存器位宽只有 16 位,所以 OPRD 不可能是寄存器操作数。

    应用举例:

    注意:寄存器间接寻址只允许使用间址寄存器 BX、BP、SI、DI 。

    2. 条件转移指令

    ① 根据前一条指令执行后的标志位状态来决定是否转移。

    ② 若满足转移条件,则转移到指定的地址;否则顺序执行下一条指令。

    ③ 所有的条件转移都是直接寻址方式的短转移,即只能在以当前 IP 值(转移指令的下一条)为中心的 -128 ∽ 127 字节范围内转移。

    由前面关于汇编的介绍可知,汇编时将会计算位移量 Disp 。而为了缩短指令长度,只用了 8 位来存储位移量,因此转移范围为 -128 ∽ 127 字节。

    ④ 条件转移不影响标志位。

    单一条件

    复合条件

    3. 循环控制指令

    ① 循环的次数必须先送入 CX 寄存器中。

    ② 控制转向的目标地址是以当前 IP 值(循环控制指令的下一条)为中心的 -128 ~ 127 字节范围内标号所代表的偏移地址。

    ③ 循环控制指令不影响状态标志位,状态标志位主要由循环控制指令之前的指令改变。

    (1)LOOP 指令

    格式:LOOP Label

    执行:① CX - 1 → CX  ② 如下

    • 若 CX ≠ 0,则 Label → IP 。
    • 若 CX = 0,则退出循环、执行下一条指令。

    LOOP Label 看似等价于:① DEC CX  ② JZ Label

    但实质不一样,因为 LOOP 不会改变 FLAGS 。

    应用举例:

    将从 Mem1 开始的 100 个字节单元清零。

    (2)LOOPZ/LOOPE 指令

    格式:LOOPZ  Label 或 LOOPE  Label

    执行:① CX - 1 → CX ② 如下

    • 若 CX ≠ 0、ZF = 1,则 Label → IP 。
    • 若 CX = 0 或 ZF = 0,则退出循环、执行下一条指令。

    FLAGS 状态标志位(ZF 位)由循环控制指令之前的指令改变。

    FLAGS 状态标志位(ZF 位)由重复前缀后的串操作指令改变。

    (3)LOOPNZ/LOOPNE 指令

    格式:LOOPNZ Label 或 LOOPNE Label

    执行:① CX - 1 → CX  ② 如下

    • 若 CX ≠ 0、ZF = 0,则 Label → IP 。
    • 若 CX = 0 或 ZF = 1,则退出循环、执行下一条指令。

    4. 过程调用和返回

    ① 调用指令 CALL

    • 保存主程序断点地址,也是返回地址
    • 子程序入口地址 → IP 或 CS 和 IP

    ② 返回指令 RET

    • 主程序返回地址 → IP 或 CS 和 IP

    过程调用和返回与中断的区别:过程调用和返回直接得到子程序入口地址,而中断需要通过查询中断向量表来得到中断服务程序入口地址。

    (1)段内直接调用

    格式:CALL  PROC

    写法:CALL XXXXH

    执行:如下

    • ① SP - 2 → SP
    • ② IP 高 8 位 → SP + 1
    • ③ IP 低 8 位 → SP
    • ④ PROC → IP

    PROC:是一个近过程的符号地址,表示指令调用的过程是在当前代码段内。指令在汇编后会得到 CALL 指令的下一条指令与被调用过程的入口地址之间相差的 16 位相对偏移量。

    (2)段内间接调用

    格式:CALL  OPRD

    执行:如下

    • ① SP - 2 → SP
    • ② IP 高 8 位 → SP + 1
    • ③ IP 低 8 位 → SP
    • ④ OPRD→ IP

    OPRD:是 16 位寄存器或两个存储器单元的内容。这个内容代表的是一个近过程的入口地址。若操作数 OPRD 是一个 16 位通用寄存器,则将寄存器的内容送 IP;若是存储单元,则将存储器的两个单元的内容送 IP。

    (3)段间直接调用

    格式:CALL  FAR  PTR  PROC(FAR  PTR 指明 PROC 是远过程,需要取 CS 和 IP)

    执行:如下

    • ① SP - 2 → SP,CS →([SP + 1],[SP])
    • ② SP - 2 → SP,IP →([SP + 1],[SP])
    • ③ 段地址 → CS,偏移地址 → IP

    用指令中给出的段地址取代 CS 的内容,偏移地址取代 IP 的内容。

    PROC:是一个远过程的符号地址,表示指令调用的过程在另外的代码段内。

    (4)段间间接调用

    格式:CALL  OPRD

    执行:如下

    • ① SP - 2 → SP,CS →([SP + 1],[SP])
    • ② SP - 2 → SP,IP →([SP + 1],[SP])
    • ③ OPRD(高 16 位) → CS,OPRD(低 16 位) → IP

    OPRD:是一个根据寻址方式而得到的 32 位存储器操作数。

    (5)返回指令 RET

    格式:RET

    执行:

    对于段内:([SP + 1],[SP])→ IP,SP + 2 → SP

    对于段间:如下

    • ① ([SP + 1],[SP])→ IP,SP + 2 → SP
    • ② ([SP + 1],[SP])→ CS,SP + 2 → SP

    RET 指令一般位于子程序的最后一条,不影响 FLAGS 状态标志位。

    5. 中断指令

    (1)中断指令 INT

    中断指令用于产生软件中断,以执行一段特殊的中断处理过程。

    格式:INT  n

    n 是中断向量码/中断类型码,取指范围为 0 ~ 255 。

    中断向量地址 = n × 4

    CPU 根据中断向量地址读取内存,取出中断服务子程序的入口地址。

    • 中断向量高 16 位 → CS
    • 中断向量低 16 位 → IP

    执行:

    TF 置为 0,即禁止单步跟踪;IF 置为 0,即关闭中断。

    没有把它们放在第一步是为了防止它们修改原来的 FLAGS 。

    (2)中断返回指令 IRET

    中断返回指令位于中断服务子程序的最后一条,用于返回被中断的程序。  

    格式:IRET

    执行:

    6. 处理器控制指令

  • 相关阅读:
    c++中stl中常见的函数
    【Unity数据交互】JsonUtility的“爱恨情仇“
    数据结构的魔法:高级算法优化实战
    开发者分享 | Ascend C算子开发及单算子调用
    leetcode-151. 颠倒字符串中的单词-20220823
    Vue
    Java进阶指南:高级面试问题与精辟解答(四)
    【跟小嘉学习区块链】二、Hyperledger Fabric 架构详解
    vs中git提交合并分支的步骤记录
    linux解压文件命令
  • 原文地址:https://blog.csdn.net/m0_64140451/article/details/128117618