汇编是如何实现指令之间的跳转

指令

  • JMP,跳转指令
  • CALL,过程调用指令
  • LOOP,循环指令

段寄存器

  • CS:code segment 指令段寄存器
  • DS:data segment 数据段寄存器
  • SS:stack segment 栈段寄存器
  • ES:不知道英文,但是是辅助段寄存器
  • fs,gs:一般存操作系统的线程本地存储

跳转指令

操作码 指令 说明
EB cb JMP rel8 相对短跳转,位移量相对于下一条指令
E9 cw JMP rel16 相对近跳转,位移量相对于下一条指令
E9 cd JMP rel32 相对近跳转,位移量相对于下一条指令
FF /4 JMP r/m16 绝对间接近跳转,地址由 r/m16 给出
FF /4 JMP r/m32 绝对间接近跳转,地址由 r/m32 给出
EA cd JMP ptr16:16 绝对远跳转,地址由操作数给出
EA cp JMP ptr16:32 绝对远跳转,地址由操作数给出
FF /5 JMP m16:16 绝对间接远跳转,地址由 m16:16 给出
FF /5 JMP m16:32 绝对间接远跳转,地址由 m16:32 给出

分为三种:

  • 段内跳转:由本段段寄存器作为基址+偏移的跳转
  • 相对跳转:由下一条指令地址作为基址+偏移的跳转
  • 远跳转:由一个段寄存器作为基址+偏移的跳转
  • 任务切换:略(切换进程/线程)

条件跳转

操作码 指令 说明
77 cb JA rel8 高于(CF=0 且 ZF=0)时短跳转
73 cb JAE rel8 高于或等于 (CF=0) 时短跳转
72 cb JB rel8 低于 (CF=1) 时短跳转
76 cb JBE rel8 低于或等于(CF=1 或 ZF=1)时短跳转
72 cb JC rel8 进位 (CF=1) 时短跳转
E3 cb JCXZ rel8 CX 寄存器为 0 时短跳转
E3 cb JECXZ rel8 ECX 寄存器为 0 时短跳转
74 cb JE rel8 等于 (ZF=1) 时短跳转
7F cb JG rel8 大于(ZF=0 且 SF=OF)时短跳转
7D cb JGE rel8 大于或等于 (SF=OF) 时短跳转
7C cb JL rel8 小于 (SF<>OF) 时短跳转
7E cb JLE rel8 小于或等于(ZF=1 或 SF<>OF)时短跳转
76 cb JNA rel8 不高于(CF=1 或 ZF=1)时短跳转
72 cb JNAE rel8 不高于或等于 (CF=1) 时短跳转
73 cb JNB rel8 不低于 (CF=0) 时短跳转
77 cb JNBE rel8 不低于或等于(CF=0 或 ZF=0)时短跳转
73 cb JNC rel8 无进位 (CF=0) 时短跳转
75 cb JNE rel8 不相等 (ZF=0) 时短跳转
7E cb JNG rel8 不大于(ZF=1 或 SF<>OF)时短跳转
7C cb JNGE rel8 不大于或等于 (SF<>OF) 时短跳转
7D cb JNL rel8 不小于 (SF=OF) 时短跳转
7F cb JNLE rel8 不小于或等于(ZF=0 且 SF=OF)时短跳转
71 cb JNO rel8 不上溢 (OF=0) 时短跳转
7B cb JNP rel8 奇校验 (PF=0) 时短跳转
79 cb JNS rel8 正数时 (SF=0) 短跳转
75 cb JNZ rel8 不为零 (ZF=0) 时短跳转
70 cb JO rel8 上溢 (OF=1) 时短跳转
7A cb JP rel8 偶校验 (PF=1) 时短跳转
7A cb JPE rel8 偶校验 (PF=1) 时短跳转
7B cb JPO rel8 奇校验 (PF=0) 时短跳转
78 cb JS rel8 负数 (SF=1) 时短跳转
74 cb JZ rel8 为零 (ZF $\leftarrow$ 1) 时短跳转
0F 87 cw/cd JA rel16/32 高于(CF=0 且 ZF=0)时近跳转
0F 83 cw/cd JAE rel16/32 高于或等于 (CF=0) 时近跳转
0F 82 cw/cd JB rel16/32 低于 (CF=1) 时近跳转
0F 86 cw/cd JBE rel16/32 低于或等于(CF=1 或 ZF=1)时近跳转
0F 82 cw/cd JC rel16/32 进位 (CF=1) 时近跳转
0F 84 cw/cd JE rel16/32 相等 (ZF=1) 时近跳转
0F 84 cw/cd JZ rel16/32 为 0 (ZF=1) 时近跳转
0F 8F cw/cd JG rel16/32 大于(ZF=0 且 SF=OF)时近跳转
操作码 指令 说明
0F 8D cw/cd JGE rel16/32 大于或等于 (SF=OF) 时近跳转
0F 8C cw/cd JL rel16/32 小于 (SF<>OF) 时近跳转
0F 8E cw/cd JLE rel16/32 小于或等于(ZF=1 或 SF<>OF)时近跳转
0F 86 cw/cd JNA rel16/32 不高于(CF=1 或 ZF=1)时近跳转
0F 82 cw/cd JNAE rel16/32 不高于或等于 (CF=1) 时近跳转
0F 83 cw/cd JNB rel16/32 不低于 (CF=0) 时近跳转
0F 87 cw/cd JNBE rel16/32 不低于或等于(CF=0 或 ZF=0)时近跳转
0F 83 cw/cd JNC rel16/32 无进位 (CF=0) 时近跳转
0F 85 cw/cd JNE rel16/32 不相等 (ZF=0) 时近跳转
0F 8E cw/cd JNG rel16/32 不大于(ZF=1 或 SF<>OF)时近跳转
0F 8C cw/cd JNGE rel16/32 不大于或等于 (SF<>OF) 时近跳转
0F 8D cw/cd JNL rel16/32 不小于 (SF=OF) 时近跳转
0F 8F cw/cd JNLE rel16/32 不小于或等于(ZF=0 且 SF=OF)时近跳转
0F 81 cw/cd JNO rel16/32 不上溢 (OF=0) 时近跳转
0F 8B cw/cd JNP rel16/32 奇校验 (PF=0) 时近跳转
0F 89 cw/cd JNS rel16/32 正数 (SF=0) 时近跳转
0F 85 cw/cd JNZ rel16/32 不为零 (ZF=0) 时近跳转
0F 80 cw/cd JO rel16/32 上溢 (OF=1) 时近跳转
0F 8A cw/cd JP rel16/32 偶校验 (PF=1) 时近跳转
0F 8A cw/cd JPE rel16/32 偶校验 (PF=1) 时近跳转
0F 8B cw/cd JPO rel16/32 奇校验 (PF=0) 时近跳转
0F 88 cw/cd JS rel16/32 负数 (SF=1) 时近跳转
0F 84 cw/cd JZ rel16/32 为 0 (ZF=1) 时近跳转

过程调用指令

操作码 指令 说明
E8 cw CALL rel16 相对近调用,位移量相对于下一条指令
E8 cd CALL rel32 相对近调用,位移量相对于下一条指令
FF /2 CALL r/m16 绝对间接近调用,地址由 r/m16 给出
FF /2 CALL r/m32 绝对间接近调用,地址由 r/m32 给出
9A cd CALL ptr16:16 绝对远调用,地址由操作数给出
9A cp CALL ptr16:32 绝对远调用,地址由操作数给出
FF /3 CALL m16:16 绝对间接远调用,地址由 m16:16 给出
FF /3 CALL m16:32 绝对间接远调用,地址由 m16:32 给出
操作码 指令 说明
C3 RET 近返回到调用过程
CB RET 远返回到调用过程
C2 iw RET imm16 近返回到调用过程,并从堆栈弹出 imm16 个字节
CA iw RET imm16 远返回到调用过程,并从堆栈弹出 imm16 个字节

retf指令:先弹出值到IP寄存器,再弹出值到CS段寄存器实现返回。

循环指令

操作码 指令 说明
E2 cb LOOP rel8 递减计数;计数 $\not =$ 0 时短跳转
E1 cb LOOPE rel8 递减计数;计数 $\not =$ 0 且 ZF=1 时短跳转
E1 cb LOOPZ rel8 递减计数;计数 $\not =$ 0 且 ZF=1 时短跳转
E0 cb LOOPNE rel8 递减计数;计数 $\not =$ 0 且 ZF=0 时短跳转
E0 cb LOOPNZ rel8 递减计数;计数 $\not =$ 0 且 ZF=0 时短跳转