| SJMP | 相对跳转,包括条件跳转(CJNE,DJNZ,JB,JBC,JC,……)和非条件SJMP指令。可寻址的偏移量为离开紧跟在相对跳转指令后面的指令的首字节-128到+127字节。当我们在代码中使用相对跳转指令时,我们必须用一个表达式来估计跳转目标的代码地址。汇编器完成所有的偏移运算。如果目标地址超出范围,汇编器会产生一条出错信息。 |
| ACALL AJMP | 块内跳转和调用只能访问程序空间的2K字节块内的地址。当跳转或调用指令被执行时,程序计数器的低11位被替换。对于Dallas 390连续型模式,块的大小为512KB或19位。如果ACALL或AJMP是块中的最后一条指令,程序计数器的高端位改变,跳转将被限制在ACALL或AJMP指令后面的程序块内。 |
| LCALL LJMP | 长跳转和调用允许访问程序空间的64K字节段中任意地址。当跳转或调用指令被执行时,程序计数器的低16位被替换。对于Dallas 390连续型模式,块的大小为16MB或24位。对于菲利浦80C51MX和英特尔/爱特梅尔WM 251:如果LCALL或LJMP是64K字节段中的最后一条指令,程序计数器的高端位改变,跳转指令将被限制在LCALL或LJMP指令后面的程序段内。 |
| ECALL EJMP | 扩展的跳转和调用允许在英特尔/爱特梅尔WM 251或菲利浦80C51MX扩展的程序空间内访问。 |
| CALL JMP | 通用跳转和调用是两条不代表具体操作码的指令助记符。JMP可以被汇编为SJMP,AJMP,LJMP,EJMP。CALL可以被汇编为ACALL,LCALL或ECALL。通用助记符通常被估计为一条指令,没有必要是最短的指令,只要达到指定的程序地址操作数就可以。 |
适用于所有8051版本的例子
| EXTRN CODE (my_function) | |||
| CSEG | AT 3 | ||
| JMP | ext_int | ; 一个中断向量 | |
| ?PR?myintr | SEGMENT | CODE | ; 为程序代码定义一个段 |
| RSEG | ?PR?myintr | ||
| ext_int: | JB | FLAG, flag_OK | |
| INC | my_var | ||
| flag_OK: | CPL | FLAG | |
| RETI | |||
| ; http://gonghighloam.21ic.org 罗亩的笔记 | |||
| ?PR?myprog | SEGMENT | CODE INBLOCK | ; 2K块内的一个段 |
| RSEG | ?PR?myprog | ||
| func1: | CALL | sub_func | ; 将产生ACALL |
| loop: | CALL | my_function | ; 外部函数 -> LCALL |
| MOV | A,my_var | ||
| JNZ | loop | ||
| RET | |||
| http://gonghighloam.21ic.org 罗亩的笔记 | |||
| sub_func: | CLR | FLAG | |
| MOV | R0, #20 | ||
| loop1: | CALL | my_function | |
| DJNZ | R0, loop1 | ||
| RET | |||
在菲利浦80C51MX和英特尔/爱特梅尔WM 251中使用EJMP,ECALL的例子
| EXTRN ECODE:FAR (my_farfunc) | |||
| Reset | EQU | ECODE 0FF0000H | ; 251上的复位地址 |
| ?PR?my_seg | SEGMENT | ECODE | ; 定义一个EDATA类型的段 |
| RSEG | ?PR?my_seg | ||
| ; http://gonghighloam.21ic.org罗亩的笔记 | |||
| func1 | PROC | FAR | ; 使用ECALL调用的FAR函数 |
| CALL | func2 | ; 产生LCALL | |
| JNB | Flag, mylab | ; 产生ECALL | |
| EJMP | Reset | ||
| mylab: | ERET | ||
| ENDP | |||
| http://gonghighloam.21ic.org 罗亩的笔记 | |||
| func2 | PROC | NEAR | |
| CALL | my_farfunc | ; 产生ECALL | |
| RET | |||
| ENDP | |||