JMP 用于直接跳转到指定的代码位置,无需判断任何条件。这在改变程序的执行流程时非常有用。JMP 目标标号)JMP 目标标号JMP START ; 跳转到标号 STARTNEAR PTR)段内直接近转移指令JMP 目标标号,显式指定跳转到同一个段内。JMP NEAR PTR 目标标号JMP NEAR PTR NEXT_STEP ; 跳转到标号 NEXT_STEPJMP SHORT)JMP SHORT 目标标号JMP SHORT LOOP_END ; 短跳转到标号 LOOP_ENDJMP WORD PTR)JMP WORD PTR [内存地址]JMP WORD PTR [BX] ; 跳转到 BX 指向的地址JMP FAR PTR)JMP FAR PTR 段:偏移JMP FAR PTR 0x1234:0x5678 ; 跳转到段 0x1234 中偏移 0x5678 的位置JMP DWORD PTR)JMP DWORD PTR [内存地址]JMP DWORD PTR [SI] ; 跳转到 SI 指向的 32 位段间地址JZ/JE: ZF=1, 0/相等则转移JNZ/JNE: ZF=0, 非0/不相等则转移JS: SF=1, 结果为负则转移JNS: SF=0, 结果为正则转移JO: OF=1, 结果溢出则转移JNO: OF=0, 结果不溢出则转移JP/JPE: PF=1, 低8位中“1”的个数为偶数则转移JNP/JPO: PF=0, 低8位中“1”的个数为奇数则转移JC: CF=1, 有进位则转移JNC: CF=0, 无进位则转移JA/JNBE: CF=0 且 ZF=0, A > B 则转移JAE/JNB: CF=0 或 ZF=1, A ≥ B 则转移JB/JNAE: CF=1 且 ZF=0, A < B 则转移JBE/JNA: CF=1 或 ZF=1, A ≤ B 则转移MOV AL, 5 ; AL = 5
MOV BL, 10 ; BL = 10
CMP AL, BL ; 比较 AL 和 BL
JA GREATER ; 如果 AL > BL 跳转到 GREATER(这里不会跳转,因为 AL < BL)
JB LESS_THAN ; 如果 AL < BL 跳转到 LESS_THAN(这里会跳转到 LESS_THAN)
JAE GREATER_EQUAL ; 如果 AL ≥ BL 跳转到 GREATER_EQUAL(这里不会跳转)
JBE LESS_THAN_OR_EQUAL ; 如果 AL ≤ BL 跳转到 LESS_THAN_OR_EQUAL(这里会跳转到 LESS_THAN_OR_EQUAL)
; 定义标号
GREATER:
; AL > BL 的处理代码
JMP END
LESS_THAN:
; AL < BL 的处理代码
JMP END
GREATER_EQUAL:
; AL ≥ BL 的处理代码
JMP END
LESS_THAN_OR_EQUAL:
; AL ≤ BL 的处理代码
JMP END
END:
; 程序结束**<font style="color:#117CEE;">JA/JNBE</font>**)CF=0 且 ZF=0 时,表示 A > B(A 大于 B),执行跳转。JA 目标标号 ; 若 A > B 则跳转CMP AX, BX ; 比较 AX 和 BX
JA GREATER ; 若 AX > BX 则跳转到 GREATER<font style="color:#117CEE;">JAE/JNB</font>)CF=0 或 ZF=1 时,表示 A ≥ B(A 大于或等于 B),执行跳转。JAE 目标标号 ; 若 A ≥ B 则跳转CMP AX, BX ; 比较 AX 和 BX
JAE NOTLESS ; 若 AX ≥ BX 则跳转到 NOTLESS<font style="color:#117CEE;">JB/JNAE</font>)CF=1 且 ZF=0 时,表示 A < B(A 小于 B),执行跳转。JB 目标标号 ; 若 A < B 则跳转CMP AX, BX ; 比较 AX 和 BX
JB LESS ; 若 AX < BX 则跳转到 LESS<font style="color:#117CEE;">JBE/JNA</font>)CF=1 或 ZF=1 时,表示 A ≤ B(A 小于或等于 B),执行跳转。JBE 目标标号 ; 若 A ≤ B 则跳转CMP AX, BX ; 比较 AX 和 BX
JBE NOTGREATER ; 若 AX ≤ BX 则跳转到 NOTGREATERCMP AX, BX ; 比较 AX 和 BX
JA GREATER ; 若 AX > BX 跳转到 GREATER
JBE LESS_EQUAL ; 否则跳转到 LESS_EQUAL
GREATER:
; 执行 AX > BX 时的代码
JMP END
LESS_EQUAL:
; 执行 AX ≤ BX 时的代码
JMP END
END:
; 程序结束在上述示例中,根据 AX 和 BX 的比较结果,程序会跳转到不同的标号来执行相应的代码。
JG/JNLE: SF=OF 且 ZF=0, A > B 则转移JGE/JNL: SF=OF 或 ZF=1, A ≥ B 则转移JL/JNGE: SF≠OF 且 ZF=0, A < B 则转移JLE/JNG: SF≠OF 或 ZF=1, A ≤ B 则转移ORG 100h ; 指令段的起始地址
MOV AL, -5 ; AL = -5
MOV BL, 3 ; BL = 3
CMP AL, BL ; 比较 AL 和 BL
; 检查是否大于
JG GREATER ; 如果 AL > BL (SF=OF 且 ZF=0) 跳转到 GREATER
; 检查是否大于等于
JGE GREATER_EQUAL ; 如果 AL ≥ BL (SF=OF 或 ZF=1) 跳转到 GREATER_EQUAL
; 检查是否小于
JL LESS_THAN ; 如果 AL < BL (SF≠OF 且 ZF=0) 跳转到 LESS_THAN
; 检查是否小于等于
JLE LESS_THAN_OR_EQUAL ; 如果 AL ≤ BL (SF≠OF 或 ZF=1) 跳转到 LESS_THAN_OR_EQUAL
; 如果没有跳转,执行默认操作
DEFAULT_ACTION:
MOV DX, OFFSET NOT_JUMPED
MOV AH, 09h
INT 21h ; 打印字符串
JMP END_PROGRAM
; 大于的处理
GREATER:
MOV DX, OFFSET GREATER_MSG
MOV AH, 09h
INT 21h ; 打印字符串
JMP END_PROGRAM
; 大于等于的处理
GREATER_EQUAL:
MOV DX, OFFSET GREATER_EQUAL_MSG
MOV AH, 09h
INT 21h ; 打印字符串
JMP END_PROGRAM
; 小于的处理
LESS_THAN:
MOV DX, OFFSET LESS_THAN_MSG
MOV AH, 09h
INT 21h ; 打印字符串
JMP END_PROGRAM
; 小于等于的处理
LESS_THAN_OR_EQUAL:
MOV DX, OFFSET LESS_THAN_OR_EQUAL_MSG
MOV AH, 09h
INT 21h ; 打印字符串
JMP END_PROGRAM
; 程序结束
END_PROGRAM:
MOV AH, 4Ch
INT 21h ; 终止程序
; 字符串数据
GREATER_MSG DB 'AL is greater than BL$', 0
GREATER_EQUAL_MSG DB 'AL is greater than or equal to BL$', 0
LESS_THAN_MSG DB 'AL is less than BL$', 0
LESS_THAN_OR_EQUAL_MSG DB 'AL is less than or equal to BL$', 0
NOT_JUMPED DB 'No jump occurred$', 0LOOP)**LOOP** 指令时,寄存器 **CX** 的值减 1。如果 **CX** 不为 0,**则跳转到指定的标号处继续执行;如果 CX 为 0,则跳出循环,继续执行下一条指令。LOOP 目标标号MOV CX, 0100H ; 设置循环次数为 256 次
DELAY:
; 这里可以是一些操作,比如 NOP
LOOP DELAY ; 每次循环结束时 CX 减 1,不为 0 则跳转到 DELAY在这个示例中,程序会在 DELAY 标号处循环 256 次,然后继续执行 LOOP DELAY 之后的代码。
LOOPE/LOOPZ)LOOPE(或 LOOPZ)指令时,寄存器 CX 的值减 1。如果 <font style="color:#DF2A3F;">CX</font> 不为 0 并且零标志位 <font style="color:#DF2A3F;">ZF</font> 为 1,则跳转到指定的标号处继续执行;否则跳出循环,继续执行下一条指令。LOOPE 目标标号 ; 或者 LOOPZ 目标标号CMP AX, BX ; 比较 AX 和 BX
MOV CX, 5 ; 设置循环次数为 5 次
L1:
; 如果 AX = BX (ZF = 1),则执行以下代码
LOOPE L1 ; 如果 CX 不为 0 且 ZF = 1,跳转到 L1在这个示例中,LOOPE L1 会在 CX 不为 0 且 ZF 为 1 的情况下跳转到 L1 继续循环。否则,将跳出循环。
LOOPNE/LOOPNZ)LOOPNE(或 LOOPNZ)指令时,寄存器 CX 的值减 1。如果 **<font style="color:#DF2A3F;">CX</font>** 不为 0 并且零标志位 **<font style="color:#DF2A3F;">ZF</font>** 为 0,则跳转到指定的标号处继续执行;否则跳出循环,继续执行下一条指令。LOOPNE 目标标号 ; 或者 LOOPNZ 目标标号CMP AX, BX ; 比较 AX 和 BX
MOV CX, 5 ; 设置循环次数为 5 次
L2:
; 如果 AX ≠ BX (ZF = 0),则执行以下代码
LOOPNE L2 ; 如果 CX 不为 0 且 ZF = 0,跳转到 L2在这个示例中,LOOPNE L2 会在 CX 不为 0 且 ZF 为 0 的情况下跳转到 L2 继续循环。否则,将跳出循环。
LOOP 指令简单地基于 CX 的值进行循环控制。LOOPE/LOOPZ 在循环时还考虑 ZF 是否为 1(表示相等或为零的情况)。LOOPNE/LOOPNZ 在循环时考虑 ZF 是否为 0(表示不相等或不为零的情况)。在汇编语言中,CALL 指令用于调用一个子程序(也叫过程或函数)。调用子程序时,程序的执行会跳转到子程序的起始位置,并在子程序执行完成后返回到调用CALL 指令的下一条指令继续执行。
CALL 指令的工作原理:CALL 指令被执行时,当前指令的下一条指令地址(即返回地址)会被压入堆栈,以便在子程序执行完成后能够返回。CALL 指定的标号处(即子程序的起始地址),开始执行子程序的代码。RET(返回)指令。RET 指令时,返回地址会从堆栈中弹出,程序控制权会返回到主程序的 CALL 指令之后的指令继续执行。CALL 标号MAIN:
; 一些主程序代码
CALL SUBROUTINE ; 调用子程序 SUBROUTINE
; 子程序执行完毕后,程序会回到这里继续执行
...
SUBROUTINE:
; 子程序的代码
RET ; 返回到调用点CALL SUBROUTINE 使得程序跳转到 SUBROUTINE 标号处执行子程序的代码。SUBROUTINE 执行完 RET 指令时,程序返回到 CALL SUBROUTINE 之后的代码,继续执行主程序。CALL 指令用于实现子程序的调用,使得代码模块化、便于复用。CALL 指令配合 RET 指令使用,确保程序在执行完子程序后能够正确返回到调用点继续执行。在汇编语言中,RET 指令用于从子程序(或函数、过程)返回到调用该子程序的主程序位置。它和 CALL 指令相配合使用,以保证在执行完子程序后,程序能够回到主程序继续执行。
RET 指令的工作原理:RET 指令被执行时,处理器会从堆栈中弹出先前 CALL 指令压入的返回地址。CALL 指令所在位置的下一条指令,继续执行主程序的代码。RETMAIN:
; 一些主程序代码
CALL SUBROUTINE ; 调用子程序 SUBROUTINE
; 子程序执行完毕后,程序会回到这里继续执行
...
SUBROUTINE:
; 子程序的代码
RET ; 返回到调用点CALL SUBROUTINE 指令调用了一个名为 SUBROUTINE 的子程序。RET 指令时,程序从堆栈中弹出返回地址,并跳回到 CALL SUBROUTINE 指令的下一条指令处,继续执行主程序。RET 指令用于结束子程序的执行,并将程序控制权返回给主程序。RET 指令,程序将无法正确返回到主程序,可能会导致程序异常或崩溃。RET 指令确保子程序执行完毕后,程序能够返回到正确的主程序位置继续执行,是实现程序流程控制的重要指令之一。