8085微处理器中CALL和JUMP指令的区别
JMP指令和CALL指令之间的主要区别如下:
如果执行JMP指令,我们将跳转到目标位置,并且执行从那里继续,而无需稍后返回到JMP之后的指令。另一方面,如果执行CALL指令,我们将跳转到子程序,并且执行从那里继续,直到在子程序中执行RET指令,然后我们返回到主程序中CALL之后的指令。
CALL指令之后下一条指令的地址称为返回地址。这是当8085执行RET指令时程序流程返回到的地址。在8085获取call指令时,PC将递增3,并将指向call之后的下一条指令。换句话说,在获取call指令时,PC将具有返回地址。
为了促进这样的返回,CALL指令首先将返回地址存储在堆栈顶部之上。只有在那之后,分支到子程序才会发生。
我们在8085中拥有不同类型的条件和无条件JUMP指令。详细信息如下:
在8085指令集中,有一组跳转指令,可以将程序控制转移到某个内存位置。因此,在这些分支助记符之后,我们将必须提及该位置的16位目标地址。这些跳转指令可以分为两类:
无条件跳转指令和
条件跳转指令
在无条件跳转指令下,只有一个助记符,即JUMP。但在条件跳转指令下,我们有8个不同的助记符。我们知道8085标志寄存器中有5个标志位。它们是S、Z、P、Cy、AC。其中,只有在AC标志位上,没有跳转指令。但对于其余4个标志位,我们有8个条件跳转指令,具体取决于它们的值为1或0,即分别为TRUE和FALSE。以下是所有分支指令的列表,如下表所示:
助记符,操作数 | 操作码(十六进制) | 字节数 |
---|---|---|
JC 标签 | DA | 3 |
JM 标签 | FA | 3 |
JMP 标签 | C3 | 3 |
JNC 标签 | D2 | 3 |
JNZ 标签 | C2 | 3 |
JP 标签 | F2 | 3 |
JPE 标签 | EA | 3 |
JPO 标签 | E2 | 3 |
JZ 标签 | CA | 3 |
下表显示了分支指令及其含义的列表。
操作码 | 操作数 | 含义 | 解释 | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
JMP | 16位地址 | 无条件跳转 | 程序序列被转移到操作数中给定的内存地址。 | |||||||||||||||||||||||||||
| 16位地址 | 条件跳转 | 根据PSW的指定标志,程序序列被转移到操作数中给定的内存地址。 |
CALL指令的主要目的和用法如下:
有时在8085汇编语言编码中,我们需要多次重复某个程序段。在这些情况下,我们可以定义子程序。在这些子程序中,我们可以包含我们重复可重用的指令集或代码。然后,根据需要,我们将相应地调用这些子程序。子程序也可以称为过程。
每当需要执行子程序中的指令时,我们使用**CALL**指令将程序控制分支到子程序。**CALL**是3字节指令,其中1字节用于操作码,2字节用于子程序的地址。**CALL**助记符代表“调用子程序”。在执行子程序中编写的指令后,我们将希望将控制返回到**CALL**指令之后编写的下一条指令,然后我们将使用助记符**RET**。这里**RET**代表从子程序返回。**RET**是1字节指令。在下表中,我们提到了**CALL**和**RET**指令的操作码和字节数:
助记符,操作数 | 操作码(十六进制) | 字节数 |
---|---|---|
CALL 标签 | CD | 3 |
RET | C9 | 1 |
让我们考虑以下示例代码以更好地解释:
地址 | 十六进制代码 | 助记符 | 注释 |
---|---|---|---|
2000 | 31 | LXI SP, 5000H | SP ← 5000H。初始化SP |
2001 | 00 | 地址的低位字节 | |
2002 | 50 | 地址的高位字节 | |
2003 | 3E | MVI A, 00H | A ← 00H,初始化累加器 |
2004 | 00 | 00H作为操作数 | |
2005 | 06 | MVI B, 01H | B ← 01H |
2006 | 01 | 01H作为操作数 | |
2007 | 0E | MVI C, 02H | C ← 02H |
2008 | 02 | 02H作为操作数 | |
2009 | 16 | MVI D, 03H | D ← 03H |
200A | 03 | 03H作为操作数 | |
200B | CD | CALL 2013H | 调用地址为2013H的子程序。因此,现在程序的控制将转移到位置2013H。并且返回地址200EH(即下一条指令的地址)将被压入堆栈顶部。结果,4FFFH(SP – 1)将包含20H,而4FFEH(SP – 2)将分别包含0EH。 |
200C | 13 | 地址的低位字节 | |
200D | 20 | 地址的高位字节 | |
200E | 21 | LXI H, 4050H | HL ← 4050H,初始化HL寄存器对。在执行RET指令后,控制将返回到此指令。4050H将具有值06H,即01H + 02H + 03H = 06H的最终和 |
200F | 50 | 地址的低位字节 | |
2010 | 40 | 地址的高位字节 | |
2011 | 77 | MOV M, A | M ← A,累加器的内容将被传输到内存位置4050H,因为它由HL寄存器对指向 |
2012 | 76 | HLT | 程序结束。 |
2013 | 80 | ADD B | A ← A + B |
2014 | 81 | ADD C | A ← A + C |
2015 | 82 | ADD D | A ← A + D |
2016 | C9 | RET | 将控制返回到地址200EH。返回地址200EH将从堆栈顶部弹出。因此,从地址4FFEH,0EH将被弹出,从地址4FFFH,20H将被弹出,并且SP将相应地将其内容恢复为初始地址5000H。 |
针对此指令**CALL 2013H**执行的时序图如下:
**总结:**因此,此指令**CALL**需要3个字节、5个机器周期(操作码获取、内存读取、内存读取、内存写入、内存写入)和18个T状态才能执行,如时序图所示。
针对此指令**RET**执行的时序图如下:
**总结:**因此,此指令**RET**需要1个字节、5个机器周期(操作码获取、内存读取、内存读取)和10个T状态才能执行,如时序图所示。
.